Xml.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
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 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.ContentHandler; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.InputSource; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.SAXException; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xml.sax.XMLReader; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParser; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlSerializer; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserFactory; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.Reader; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.StringReader; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.UnsupportedEncodingException; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.xml.ExpatPullParser; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.xml.ExpatReader; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * XML utility methods. 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Xml { 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link org.xmlpull.v1.XmlPullParser} "relaxed" feature name. 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see <a href="http://xmlpull.org/v1/doc/features.html#relaxed"> 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specification</a> 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static String FEATURE_RELAXED = ExpatPullParser.FEATURE_RELAXED; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parses the given xml string and fires events on the given SAX handler. 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void parse(String xml, ContentHandler contentHandler) 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws SAXException { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XMLReader reader = new ExpatReader(); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reader.setContentHandler(contentHandler); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reader.parse(new InputSource(new StringReader(xml))); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project catch (IOException e) { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new AssertionError(e); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parses xml from the given reader and fires events on the given SAX 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * handler. 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void parse(Reader in, ContentHandler contentHandler) 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IOException, SAXException { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XMLReader reader = new ExpatReader(); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reader.setContentHandler(contentHandler); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reader.parse(new InputSource(in)); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Parses xml from the given input stream and fires events on the given SAX 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * handler. 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void parse(InputStream in, Encoding encoding, 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentHandler contentHandler) throws IOException, SAXException { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XMLReader reader = new ExpatReader(); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reader.setContentHandler(contentHandler); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputSource source = new InputSource(in); 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project source.setEncoding(encoding.expatName); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reader.parse(source); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new AssertionError(e); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a new pull parser with namespace support. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p><b>Note:</b> This is actually slower than the SAX parser, and it's not 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fully implemented. If you need a fast, mostly implemented pull parser, 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use this. If you need a complete implementation, use KXML. 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static XmlPullParser newPullParser() { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ExpatPullParser parser = new ExpatPullParser(); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parser.setNamespaceProcessingEnabled(true); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return parser; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a new xml serializer. 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static XmlSerializer newSerializer() { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return XmlSerializerFactory.instance.newSerializer(); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (XmlPullParserException e) { 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new AssertionError(e); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Factory for xml serializers. Initialized on demand. */ 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static class XmlSerializerFactory { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TYPE 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer"; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final XmlPullParserFactory instance; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project instance = XmlPullParserFactory.newInstance(TYPE, null); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (XmlPullParserException e) { 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new AssertionError(e); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Supported character encodings. 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public enum Encoding { 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project US_ASCII("US-ASCII"), 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UTF_8("UTF-8"), 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UTF_16("UTF-16"), 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ISO_8859_1("ISO-8859-1"); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String expatName; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Encoding(String expatName) { 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.expatName = expatName; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Finds an encoding by name. Returns UTF-8 if you pass {@code null}. 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static Encoding findEncodingByName(String encodingName) 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws UnsupportedEncodingException { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (encodingName == null) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Encoding.UTF_8; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Encoding encoding : Encoding.values()) { 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (encoding.expatName.equalsIgnoreCase(encodingName)) 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return encoding; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new UnsupportedEncodingException(encodingName); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return an AttributeSet interface for use with the given XmlPullParser. 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the given parser itself implements AttributeSet, that implementation 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is simply returned. Otherwise a wrapper class is 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instantiated on top of the XmlPullParser, as a proxy for retrieving its 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attributes, and returned to you. 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parser The existing parser for which you would like an 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AttributeSet. 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return An AttributeSet you can use to retrieve the 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attribute values at each of the tags as the parser moves 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * through its XML document. 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AttributeSet 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static AttributeSet asAttributeSet(XmlPullParser parser) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (parser instanceof AttributeSet) 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? (AttributeSet) parser 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : new XmlPullAttributes(parser); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 186