android.util.Xml 分析

/**
* 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);
    }
}


  1. 先看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.



你可能感兴趣的:(xml,android)