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