StAX解析器
StAX解析器是一种“拉解析器(pull parser)”,与安装事件处理器不同,你只需要使用下面的基本循环来迭代所有事件:
1 | InputStream in = url.openStream(); |
例如,在解析下面的片段时
1 | <font> |
解析器将产生下面的事件:
- START_ELEMENT,元素名:font
- CHARACTERS,内容:空白字符
- START_ELEMENT,元素名:name
- CHARACTERS,内容:Helvetica
- END_ELEMENT,元素名:name
- CHARACTERS,内容:空白字符
- START_ELEMENT,元素名:size
- CHARACTERS,内容:78
- END_ELEMENT,元素名:size
- CHARACTERS,内容:空白字符
- END_ELEMENT,元素名:font
默认情况下命名空间是使能的,你可以通过修改下面的工厂来使其无效:
1 | factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE,false); |
示例程序如下:
1 | package staxtest; |
结果截图:
生成XML文档
现在你已经知道怎样编写读取XML的java程序了,下面让我们开始介绍他的反向过程。当然你可以选择直接通过一系列print调用,打印出各元素,属性和文本内容来编写XML文件,但其实有更好的办法。
DOM/XSLT方式
可以使用文档的内容构建一棵DOM树,然后写出该树的所有内容。步骤如下:
通过调用DocumentBuilder类的newDocument方法得到一个空文档
1
Document doc = builder.newDocument();
使用Document类的createElement可以构建文档里的元素
1
2Element rootElement= doc.createElement(rootName);
Element childElement=doc.createElement(childName);使用createTextNode方法可以构建文本节点
1
Text textNode=doc.createTextNode(textcontents);
使用以下方法可以给文档加上根元素,给父元素加上子节点
1
2
3doc.appendChild(rootElement);
rootElement.appendChild(childElement);
childElement.appendChild(textNode);如果要设置元素属性的话:
1
rootElement.setAttribute(name,value);
使用XSTL将DOM树写入到输出流:
1
2
3
4
5
6
7
8
9File f = chooser.getSelectedFile();//得到输出流目标目标文件
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
"http://www.w3.org/TR/2000/CR-SVG-20000802/DTD/svg-20000802.dtd");
t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "-//W3C//DTD SVG 20000802//EN");
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty(OutputKeys.METHOD, "xml");
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
t.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(f)));
使用StAX写XML文档
SaAX API使我们可以直接将XML树写出,不用构建DOM树,这需要从某个OutputStream中构建一个XMLstreamWriter。步骤如下
先得到一个XMLstreamWriter对象
1
2XMLOutputFactory factory=XMLOutputFactory.newInstance();
XMLStreamWriter writer=factory.createXMLStreamWriter(out);//out是个输出流对象产生XML文件头
1
writer.writeStartDocument();
添加元素
1
writer.writeStartElement(name);
添加属性
1
writer.writeAttribute(name,value);
现在,可以再次通过第三步来添加新的子节点,或者通过下面的语句写出字符
1
writer.writeCharacters(text);
在添加完所有的子节点后,调用下面的方法会使当前元素被关闭
1
writer.writeEndElement();
写出没有子节点的元素(如:< img …/>),可以使用下面的调用
1
writer.writeEmptyElement(name);
最后在文档的结尾调用:
1
writer.writeEndDocument();
与使用DOM/XSLT方式一样,我们不必担心属性值和字符数据中的转义字符,但是,我们仍旧有可能会产生非良构的XML,例如具有多个根节点的文档。并且,StAX当前的版本还没有任何对产生缩进输出的支持
示例程序如下:
1 | package xmlwritetest; |