Xml.java revision 28e3f101707c7a03dcc774b9b0e6d95d68b3752d
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.util;
18
19import org.xml.sax.ContentHandler;
20import org.xml.sax.InputSource;
21import org.xml.sax.SAXException;
22import org.xml.sax.XMLReader;
23import org.xmlpull.v1.XmlPullParser;
24import org.xmlpull.v1.XmlSerializer;
25import org.xmlpull.v1.XmlPullParserException;
26import org.xmlpull.v1.XmlPullParserFactory;
27
28import java.io.IOException;
29import java.io.InputStream;
30import java.io.Reader;
31import java.io.StringReader;
32import java.io.UnsupportedEncodingException;
33
34import org.apache.harmony.xml.ExpatPullParser;
35import org.apache.harmony.xml.ExpatReader;
36
37/**
38 * XML utility methods.
39 */
40public class Xml {
41
42    /**
43     * {@link org.xmlpull.v1.XmlPullParser} "relaxed" feature name.
44     *
45     * @see <a href="http://xmlpull.org/v1/doc/features.html#relaxed">
46     *  specification</a>
47     */
48    public static String FEATURE_RELAXED = ExpatPullParser.FEATURE_RELAXED;
49
50    /**
51     * Parses the given xml string and fires events on the given SAX handler.
52     */
53    public static void parse(String xml, ContentHandler contentHandler)
54            throws SAXException {
55        try {
56            XMLReader reader = new ExpatReader();
57            reader.setContentHandler(contentHandler);
58            reader.parse(new InputSource(new StringReader(xml)));
59        }
60        catch (IOException e) {
61            throw new AssertionError(e);
62        }
63    }
64
65    /**
66     * Parses xml from the given reader and fires events on the given SAX
67     * handler.
68     */
69    public static void parse(Reader in, ContentHandler contentHandler)
70            throws IOException, SAXException {
71        XMLReader reader = new ExpatReader();
72        reader.setContentHandler(contentHandler);
73        reader.parse(new InputSource(in));
74    }
75
76    /**
77     * Parses xml from the given input stream and fires events on the given SAX
78     * handler.
79     */
80    public static void parse(InputStream in, Encoding encoding,
81            ContentHandler contentHandler) throws IOException, SAXException {
82        XMLReader reader = new ExpatReader();
83        reader.setContentHandler(contentHandler);
84        InputSource source = new InputSource(in);
85        source.setEncoding(encoding.expatName);
86        reader.parse(source);
87    }
88
89    /**
90     * Creates a new pull parser with namespace support.
91     *
92     * <p><b>Note:</b> This is actually slower than the SAX parser, and it's not
93     *   fully implemented. If you need a fast, mostly implemented pull parser,
94     *   use this. If you need a complete implementation, use KXML.
95     */
96    public static XmlPullParser newPullParser() {
97        ExpatPullParser parser = new ExpatPullParser();
98        parser.setNamespaceProcessingEnabled(true);
99        return parser;
100    }
101
102    /**
103     * Creates a new xml serializer.
104     */
105    public static XmlSerializer newSerializer() {
106        try {
107            return XmlSerializerFactory.instance.newSerializer();
108        } catch (XmlPullParserException e) {
109            throw new AssertionError(e);
110        }
111    }
112
113    /** Factory for xml serializers. Initialized on demand. */
114    static class XmlSerializerFactory {
115        static final String TYPE
116                = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer";
117        static final XmlPullParserFactory instance;
118        static {
119            try {
120                instance = XmlPullParserFactory.newInstance(TYPE, null);
121            } catch (XmlPullParserException e) {
122                throw new AssertionError(e);
123            }
124        }
125    }
126
127    /**
128     * Supported character encodings.
129     */
130    public enum Encoding {
131
132        US_ASCII("US-ASCII"),
133        UTF_8("UTF-8"),
134        UTF_16("UTF-16"),
135        ISO_8859_1("ISO-8859-1");
136
137        final String expatName;
138
139        Encoding(String expatName) {
140            this.expatName = expatName;
141        }
142    }
143
144    /**
145     * Finds an encoding by name. Returns UTF-8 if you pass {@code null}.
146     */
147    public static Encoding findEncodingByName(String encodingName)
148            throws UnsupportedEncodingException {
149        if (encodingName == null) {
150            return Encoding.UTF_8;
151        }
152
153        for (Encoding encoding : Encoding.values()) {
154            if (encoding.expatName.equalsIgnoreCase(encodingName))
155                return encoding;
156        }
157        throw new UnsupportedEncodingException(encodingName);
158    }
159
160    /**
161     * Return an AttributeSet interface for use with the given XmlPullParser.
162     * If the given parser itself implements AttributeSet, that implementation
163     * is simply returned.  Otherwise a wrapper class is
164     * instantiated on top of the XmlPullParser, as a proxy for retrieving its
165     * attributes, and returned to you.
166     *
167     * @param parser The existing parser for which you would like an
168     *               AttributeSet.
169     *
170     * @return An AttributeSet you can use to retrieve the
171     *         attribute values at each of the tags as the parser moves
172     *         through its XML document.
173     *
174     * @see AttributeSet
175     */
176    public static AttributeSet asAttributeSet(XmlPullParser parser) {
177        return (parser instanceof AttributeSet)
178                ? (AttributeSet) parser
179                : new XmlPullAttributes(parser);
180    }
181}
182