/** * api 23 的源码 */ public class Xml { /** @hide */ public Xml() {} /** * {@link org.xmlpull.v1.XmlPullParser} "relaxed" feature name. * @see <a href="http://xmlpull.org/v1/doc/features.html#relaxed"> * specification</a> */ public static String FEATURE_RELAXED = "http://xmlpull.org/v1/doc/features.html#relaxed"; /** * Parses the given xml string and fires events on the given SAX handler. */ public static void parse(String xml, ContentHandler contentHandler) throws SAXException { try { XMLReader reader = new ExpatReader(); reader.setContentHandler(contentHandler); reader.parse(new InputSource(new StringReader(xml))); } catch (IOException e) { throw new AssertionError(e); } } /** * Parses xml from the given reader and fires events on the given SAX * handler. */ public static void parse(Reader in, ContentHandler contentHandler) throws IOException, SAXException { XMLReader reader = new ExpatReader(); reader.setContentHandler(contentHandler); reader.parse(new InputSource(in)); } /** * Parses xml from the given input stream and fires events on the given SAX * handler. */ public static void parse(InputStream in, Encoding encoding, ContentHandler contentHandler) throws IOException, SAXException { XMLReader reader = new ExpatReader(); reader.setContentHandler(contentHandler); InputSource source = new InputSource(in); source.setEncoding(encoding.expatName); reader.parse(source); } /** * Returns a new pull parser with namespace support. */ public static XmlPullParser newPullParser() { try { KXmlParser parser = new KXmlParser(); parser.setFeature(XmlPullParser.FEATURE_PROCESS_DOCDECL, true); parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); return parser; } catch (XmlPullParserException e) { throw new AssertionError(); } } /** * Creates a new xml serializer. */ public static XmlSerializer newSerializer() { try { return XmlSerializerFactory.instance.newSerializer(); } catch (XmlPullParserException e) { throw new AssertionError(e); } } /** Factory for xml serializers. Initialized on demand. */ static class XmlSerializerFactory { static final String TYPE = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer"; static final XmlPullParserFactory instance; static { try { instance = XmlPullParserFactory.newInstance(TYPE, null); } catch (XmlPullParserException e) { throw new AssertionError(e); } } } /** * Supported character encodings. */ public enum Encoding { US_ASCII("US-ASCII"), UTF_8("UTF-8"), UTF_16("UTF-16"), ISO_8859_1("ISO-8859-1"); final String expatName; Encoding(String expatName) { this.expatName = expatName; } } /** * Finds an encoding by name. Returns UTF-8 if you pass {@code null}. */ public static Encoding findEncodingByName(String encodingName) throws UnsupportedEncodingException { if (encodingName == null) { return Encoding.UTF_8; } for (Encoding encoding : Encoding.values()) { if (encoding.expatName.equalsIgnoreCase(encodingName)) return encoding; } throw new UnsupportedEncodingException(encodingName); } /** * Return an AttributeSet interface for use with the given XmlPullParser. * If the given parser itself implements AttributeSet, that implementation * is simply returned. Otherwise a wrapper class is * instantiated on top of the XmlPullParser, as a proxy for retrieving its * attributes, and returned to you. * * @param parser The existing parser for which you would like an * AttributeSet. * * @return An AttributeSet you can use to retrieve the * attribute values at each of the tags as the parser moves * through its XML document. * * @see AttributeSet */ public static AttributeSet asAttributeSet(XmlPullParser parser) { return (parser instanceof AttributeSet) ? (AttributeSet) parser : new XmlPullAttributes(parser); } }
先看3个重载的parse方法
public static void parse(String xml, ContentHandler contentHandler);
public static void parse(Reader in, ContentHandler contentHandler);
public static void parse(InputStream in, Encoding encoding, ContentHandler contentHandler) ;
根据输入的类型 有String, Reader , InputStream 三种, InputStream还必须指定文本编码方式,
对输入的xml来源封装成InputSource对象,
对Xml的处理生成一个ExpatReader 对象, 这个继承自XMLReader
解析则是调用XMLReader.parse(InputSource)来解析
2. InputSource 对象 就是一个javaBean, 位于 org.xml.sax包下
几个属性:
private String publicId; private String systemId; private InputStream byteStream; private String encoding; private Reader characterStream;
3. ExpadReader 对象 ,位于 org.apache.harmony.xml包
有一个静态内部类 Feature ,标识 xml的uri
private static class Feature { private static final String BASE_URI = "http://xml.org/sax/features/"; private static final String VALIDATION = BASE_URI + "validation"; private static final String NAMESPACES = BASE_URI + "namespaces"; private static final String NAMESPACE_PREFIXES = BASE_URI + "namespace-prefixes"; private static final String STRING_INTERNING = BASE_URI + "string-interning"; private static final String EXTERNAL_GENERAL_ENTITIES = BASE_URI + "external-general-entities"; private static final String EXTERNAL_PARAMETER_ENTITIES = BASE_URI + "external-parameter-entities"; }
方法:
//判断name 是不是对应于 Feature中的uri标识,不是则false public boolean getFeature(String name); //设置uri的标识的bool值 public void setFeature(String name, boolean value); // 如果 name.equal("http://xml.org/sax/properties/lexical-handler")才返回一个lexicalHandler,否则报错 public Object getProperty(String name); //同getProperty()只能设置LEXICAL_HANDLER_PROPERTY的, value 强转成LexicalHandler public void setProperty(String name, Object value); //几个set,get方法: setEntityResolver(resolver); getEntityResolver(resolver); //XXX代表:DTD, Content, Error, Lexical setXXXHandler(handler); getXXXHandler(); //重点的parse方法 private void parse(Reader in, String publicId, String systemId); private void parse(InputStream in, String charsetName, String publicId, String systemId); public void parse(String systemId);
不管是InputStream还是Reader,都是生成一个 ExpadParser对象,调用expadParser.parseDocument();来解析
4 . ExpatParser同样位于 org.apache.harmony.xml包中, 这个才是解析xml的main方法
void parseDocument(InputStream in) throws IOException, SAXException { startDocument(); parseFragment(in); finish(); endDocument(); }
5. 还有一个ContentHandler 接口 , 在org.apache.harmony.xml包中,
在调用Xml.parse()时作为第二个参数传递进来的, 这个传递给了XMLReader的
setContentHandler(contentHandler)方法, 作为XMLReader的一个属性
然后在XMLReader.parse()时,生成的ExpatParser时,XMLReader作为一个参数传递给了ExpatParser,
在ExpatParser调用parseDocument时,
在执行方法startDocument(), endDocument()其实都是要调用 contentHandler的方法startDocument(), endDocument()
关于ContentHandler的详细方法,可见
http://blog.csdn.net/buaalei/article/details/6052061
这个Xml对象的使用就是SAX解析, 只是比较简单, 同时主要是实现接口ContentHandler,
这儿有个例子可供参考 http://sinye.iteye.com/blog/763895.