19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.util; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1908065b9f09ead8895d97b2971622af8c179e1768Brian Carlstromimport java.io.IOException; 2008065b9f09ead8895d97b2971622af8c179e1768Brian Carlstromimport java.io.InputStream; 2108065b9f09ead8895d97b2971622af8c179e1768Brian Carlstromimport java.io.Reader; 2208065b9f09ead8895d97b2971622af8c179e1768Brian Carlstromimport java.io.StringReader; 2308065b9f09ead8895d97b2971622af8c179e1768Brian Carlstromimport java.io.UnsupportedEncodingException; 2408065b9f09ead8895d97b2971622af8c179e1768Brian Carlstromimport org.apache.harmony.xml.ExpatReader; 2508065b9f09ead8895d97b2971622af8c179e1768Brian Carlstromimport org.kxml2.io.KXmlParser; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.ContentHandler; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.InputSource; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.SAXException; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.XMLReader; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserFactory; 3308065b9f09ead8895d97b2971622af8c179e1768Brian Carlstromimport org.xmlpull.v1.XmlSerializer; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * XML utility methods. 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Xml { 39a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson /** @hide */ public Xml() {} 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link org.xmlpull.v1.XmlPullParser} "relaxed" feature name. 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see <a href="http://xmlpull.org/v1/doc/features.html#relaxed"> 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specification</a> 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4708065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom public static String FEATURE_RELAXED = "http://xmlpull.org/v1/doc/features.html#relaxed"; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parses the given xml string and fires events on the given SAX handler. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void parse(String xml, ContentHandler contentHandler) 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws SAXException { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XMLReader reader = new ExpatReader(); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reader.setContentHandler(contentHandler); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reader.parse(new InputSource(new StringReader(xml))); 5808065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom } catch (IOException e) { 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new AssertionError(e); 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parses xml from the given reader and fires events on the given SAX 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * handler. 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void parse(Reader in, ContentHandler contentHandler) 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException, SAXException { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XMLReader reader = new ExpatReader(); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reader.setContentHandler(contentHandler); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reader.parse(new InputSource(in)); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parses xml from the given input stream and fires events on the given SAX 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * handler. 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void parse(InputStream in, Encoding encoding, 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentHandler contentHandler) throws IOException, SAXException { 8028e3f101707c7a03dcc774b9b0e6d95d68b3752dTom O'Neill XMLReader reader = new ExpatReader(); 8128e3f101707c7a03dcc774b9b0e6d95d68b3752dTom O'Neill reader.setContentHandler(contentHandler); 8228e3f101707c7a03dcc774b9b0e6d95d68b3752dTom O'Neill InputSource source = new InputSource(in); 8328e3f101707c7a03dcc774b9b0e6d95d68b3752dTom O'Neill source.setEncoding(encoding.expatName); 8428e3f101707c7a03dcc774b9b0e6d95d68b3752dTom O'Neill reader.parse(source); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8808065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom * Returns a new pull parser with namespace support. 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static XmlPullParser newPullParser() { 9108065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom try { 9208065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom KXmlParser parser = new KXmlParser(); 9308065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom parser.setFeature(XmlPullParser.FEATURE_PROCESS_DOCDECL, true); 9408065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); 9508065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom return parser; 9608065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom } catch (XmlPullParserException e) { 9708065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom throw new AssertionError(); 9808065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom } 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a new xml serializer. 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static XmlSerializer newSerializer() { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return XmlSerializerFactory.instance.newSerializer(); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (XmlPullParserException e) { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new AssertionError(e); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Factory for xml serializers. Initialized on demand. */ 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class XmlSerializerFactory { 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TYPE 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer"; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final XmlPullParserFactory instance; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project instance = XmlPullParserFactory.newInstance(TYPE, null); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (XmlPullParserException e) { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new AssertionError(e); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Supported character encodings. 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public enum Encoding { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project US_ASCII("US-ASCII"), 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UTF_8("UTF-8"), 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UTF_16("UTF-16"), 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ISO_8859_1("ISO-8859-1"); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String expatName; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Encoding(String expatName) { 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.expatName = expatName; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Finds an encoding by name. Returns UTF-8 if you pass {@code null}. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static Encoding findEncodingByName(String encodingName) 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws UnsupportedEncodingException { 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (encodingName == null) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Encoding.UTF_8; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Encoding encoding : Encoding.values()) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (encoding.expatName.equalsIgnoreCase(encodingName)) 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return encoding; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new UnsupportedEncodingException(encodingName); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 158a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return an AttributeSet interface for use with the given XmlPullParser. 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the given parser itself implements AttributeSet, that implementation 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is simply returned. Otherwise a wrapper class is 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instantiated on top of the XmlPullParser, as a proxy for retrieving its 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attributes, and returned to you. 165a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson * 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parser The existing parser for which you would like an 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AttributeSet. 168a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson * 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return An AttributeSet you can use to retrieve the 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attribute values at each of the tags as the parser moves 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * through its XML document. 172a0f8bc51aff98c2e23e73069e447f63397471a0aJesse Wilson * 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AttributeSet 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static AttributeSet asAttributeSet(XmlPullParser parser) { 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (parser instanceof AttributeSet) 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? (AttributeSet) parser 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : new XmlPullAttributes(parser); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 181