Xml.java revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
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        try {
83            XMLReader reader = new ExpatReader();
84            reader.setContentHandler(contentHandler);
85            InputSource source = new InputSource(in);
86            source.setEncoding(encoding.expatName);
87            reader.parse(source);
88        } catch (IOException e) {
89            throw new AssertionError(e);
90        }
91    }
92
93    /**
94     * Creates a new pull parser with namespace support.
95     *
96     * <p><b>Note:</b> This is actually slower than the SAX parser, and it's not
97     *   fully implemented. If you need a fast, mostly implemented pull parser,
98     *   use this. If you need a complete implementation, use KXML.
99     */
100    public static XmlPullParser newPullParser() {
101        ExpatPullParser parser = new ExpatPullParser();
102        parser.setNamespaceProcessingEnabled(true);
103        return parser;
104    }
105
106    /**
107     * Creates a new xml serializer.
108     */
109    public static XmlSerializer newSerializer() {
110        try {
111            return XmlSerializerFactory.instance.newSerializer();
112        } catch (XmlPullParserException e) {
113            throw new AssertionError(e);
114        }
115    }
116
117    /** Factory for xml serializers. Initialized on demand. */
118    static class XmlSerializerFactory {
119        static final String TYPE
120                = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer";
121        static final XmlPullParserFactory instance;
122        static {
123            try {
124                instance = XmlPullParserFactory.newInstance(TYPE, null);
125            } catch (XmlPullParserException e) {
126                throw new AssertionError(e);
127            }
128        }
129    }
130
131    /**
132     * Supported character encodings.
133     */
134    public enum Encoding {
135
136        US_ASCII("US-ASCII"),
137        UTF_8("UTF-8"),
138        UTF_16("UTF-16"),
139        ISO_8859_1("ISO-8859-1");
140
141        final String expatName;
142
143        Encoding(String expatName) {
144            this.expatName = expatName;
145        }
146    }
147
148    /**
149     * Finds an encoding by name. Returns UTF-8 if you pass {@code null}.
150     */
151    public static Encoding findEncodingByName(String encodingName)
152            throws UnsupportedEncodingException {
153        if (encodingName == null) {
154            return Encoding.UTF_8;
155        }
156
157        for (Encoding encoding : Encoding.values()) {
158            if (encoding.expatName.equalsIgnoreCase(encodingName))
159                return encoding;
160        }
161        throw new UnsupportedEncodingException(encodingName);
162    }
163
164    /**
165     * Return an AttributeSet interface for use with the given XmlPullParser.
166     * If the given parser itself implements AttributeSet, that implementation
167     * is simply returned.  Otherwise a wrapper class is
168     * instantiated on top of the XmlPullParser, as a proxy for retrieving its
169     * attributes, and returned to you.
170     *
171     * @param parser The existing parser for which you would like an
172     *               AttributeSet.
173     *
174     * @return An AttributeSet you can use to retrieve the
175     *         attribute values at each of the tags as the parser moves
176     *         through its XML document.
177     *
178     * @see AttributeSet
179     */
180    public static AttributeSet asAttributeSet(XmlPullParser parser) {
181        return (parser instanceof AttributeSet)
182                ? (AttributeSet) parser
183                : new XmlPullAttributes(parser);
184    }
185}
186