XML 解析

Wu Jun 2020-01-01 22:43:49
Categories: > > Tags:

xml 文件除了给开发者看,更多的情况使用程序读取 xml 文件的内容。读取 xml 文档的过程就是 xml 解析

1 XML解析方式

Java库提供了两种XML解析器:

1.1 树型解析器:DOM 解析

DOM 解析器一次性把整个xml文档加载进内存,然后在内存中构建一个 Document 的对象树,通过 Document 对象,得到树上的节点对象,通过节点对象访问(操作)到 xml 文档的内容

1.2 流机制解析器:SAX 解析

DOM 解析对内存要求较高,处理大容量的 xml 文件容易溢出

SAX 解析原理是加载一点,读取一点,处理一点。对内存的要求较低。

2 DOM 解析

Document 对象是 XML 文档的树型结构在内存中的表示方式,它由实现了 Node 接口及其各种子接口的类的对象构成。

Document树只有一个根标签,树上的分支叫做节点(Node)

2.1 DocumentBuilder

要读入一个 XML 文档,首先需要一个 DocumentBuilder 对象,可以从 DocumentBuilderFactory 获取

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

2.2 读取文档

从文件

File f = ...;
Doucument doc = builder.parse(f);

从URL

URL u = ...;
Document doc = builder.parse(u);

从任意输入流

InputStream in = ...;
Document doc = builder.parse(in);

2.3 分析文档

1)获取元素
根元素
Element root = doc.getDocumentElement();
子元素

返回子元素集合,包含元素间空白

NodeList children = root.getChildNodes();

忽略空白字符

for(int i = 0; i < children.getLengrh(); i++){
    Node child = children.item(i);
    if(child instanceif Element){
        Element childElement = (Element)child;
        ...
    }
}

getFirstChild\getLastChild

兄弟元素

getNextSibling

2)取值
标签名
String tagName = root.getTagName();
文本值

getData 获取存储在 Text 节点中的字符串

属性

getAttributes 返回包含了描述属性的 NamedNodeMap。

NamedNodeMap attributes = element.getAttributes();
for(int i = 0; i < attributes.getLengrh(); i++){
    Node attribute = attributes.item(i);
    String name = attribute.getNodeName();
    String value = attribute.getNodeValue();
}

getAttribute(name)

如果文档很大,并且处理算法又非常简单,可以在运行时解析节点,而不必看到完整的树形结构,应该使用流机制解析器(streaming parser)。

Java类库提供的流机制解析器:老而弥坚的SAX解析器和添加到Java SE 6中的更现代化的StAX解析器。SAX解析器使用的是事件回调(event callback),而StAX解析器提供了遍历解析事件的迭代器,后者用起来通常更方便一些。

3 SAX 解析器

3.1 获得SAX解析器

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();

3.2 解析文档

parser.parse(source, handler);

source 可以是一个文件、一个URL字符串或者是一个输入流。handler 属于 DefaultHandler 的一个子类,包括 ContentHandler,DTDHandler,EntityResolver,ErrorHandler。

ContentHandler 接口定义了若干个在解析文档时解析器会调用的回调方法。

4 StAX 解析器

StAX 解析器是一种“拉解析器(pull parser)”

InputStream in = url.openStream();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader parser = factory.createXMLStreamReader(in);
while(parser.hasNext()){
    int event = parser.next();
    //Call parser methods 
}

XMLStreamReader 的 getAttributeValue 获取当前元素属性

String units = parser.getAttributeValue(null, "units");