在实际工作中,对 XML
文件的操作是非常常见的,在此将对 XML
文件的解析展开讨论,与大家分享一下,希望以后工作中遇到能够快速上手。
XML 解析
在 xml
文件中由于更多的是描述信息的内容,所以在得到一个 xml 文档之后应该利用程序按照里面元素的定义名称取出对应的内容,这一过程就称为 xml 解析。
解析 xml 文件的 4 种方式:
DOM
SAX
JDOM
DOM4J
文档对象模型(DOM)
它定义了 XML 文档的逻辑结构,给出了一种访问和处理 XML 文档的方法。利用 DOM,程序开发人员可以动态地创建文档,遍历文档结构,添加、修改、删除文档内容,改变文档的显示方式等等。
DOM
这个层次的结构是一棵根据 XML
文档生成的节点树。在这棵节点树中,有一个根节点--Document
节点,所有其他的节点都是根节点的后代节点。节点树生成之后,就可以通过 DOM
接口访问、修改、添加、删除、创建树中的节点和内容。
读入 xml:
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
// 获取解析器
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析xml文档
Document doc = builder.parse(new File("src\\dom.xml"));
Element root = builder.getDocumentElement();//获得根元素
写回xml:
TransformerFactory tfactory=TransformerFactory.newInstance();
Transformer tformer = tfactory.newTransformer();
tformer.transform(new DOMSource(doc), new StreamResult(new FileOutputStream("src\\dom1.xml")));
得到文档模型的根元素
Element root = doc.getDocumentElement();
元素Element的函数:
String getTagName() -得到标签的名字
String getAttribute(“unit”) -得到元素的unit属性值
节点Node的函数:
NodeList getChildNodes() - 得到子节点的集合
Node getFirstChild() - 得到第一个子节点
Node getLastChild() - 得到最后一个子节点
节点Node的函数:
Node getNextSibling() - 得到下一个兄弟节点
Node getPreviousSibling() - 得到前一个兄弟结点
Node getParentNode() - 得到父节点
NamedNodeMap getAttributes() - 得到所有的属性集合
String getNodeName() - 得到当前节点的名字
String getNodeValue() - 得到当前节点的值
NodeList的函数
int getLength() -得到集合长度
Node item(int index) - 得到集合中的一个元素
写XML文档函数
DocumentBuilder 的函数:
Document doc = builder.newDocument(); -新建一个模型
Document 的函数:
Element createElement(String name) – 建立一个元素
Text createTextNode(String data)-创建一个文本节点
Node的函数:
Node appendChild(Node child) - 添加一个子节点
Element 的函数:
void setAttribute(String name, String value) - 设置元素的一个属性和属性值
复制代码
简单应用程序接口(SAX)
SAX
是一种事件驱动的接口,它的基本原理是由接口的用户提供符合定义的处理器,XML
分析时遇到特定的事件,就去调用处理器中特定事件的处理函数。
捕获和响应各个事件:
startDocument( )
和 endDocument( )
事件是在文档的起始处和结束处被激发的
startElement( )
和 endElement( )
事件是在遇到起始标记和结束标记时被激发的
characters( )
事件是在遇到字符数据时被激发的
使用 SAX
解析 XML
文档的步骤如下:
(1)创建 SAXParserFactory
的实例
(2)创建 SAXParser
的实例
(3)创建 SAXParserHandler
类
(4)使用 parse()
方法解析 XML
文档
SAXParserFactory spfactory = SAXParserFactory.newInstance();
// 生成SAX解析对象
SAXParser parser = spfactory.newSAXParser();
// 指定XML文件,进行XML解析
parser.parse(new File("src\\dom.xml"), new SaxReader());
复制代码
Jdom
JDOM
使用标准的 Java
编码模式,用以来弥补 DOM
及 SAX
在实际应用当中的不足之处。
这些不足之处主要在于 SAX
没有文档修改、随机访问以及输出的功能,而对于 DOM
来说,在使用时来用起来不太方便。
在 JDOM
中,XML
元素就是 Element
的实例,XML
属性就是 Attribute
的实例,XML
文档本身就是 Document
的实例。
因为 JDOM
对象就是像 Document
、Element
和 Attribute
这些类的直接实例,因此创建一个新 JDOM
对象就如在 Java
语言中使用 new
操作符一样容易。而不使用复杂的工厂化模式,使对象操作更为方便。
Document 类操作:
Element root=new Element("GREETING");
Document doc=new Document(root);
root.setText("HelloJDOM!");
复制代码
Attribute
类操作:
Attribute rootAttri = new Attribute("comment","introduce myself");//创建名为 commnet,值为 introduce myself 的属性。
rootElement.setAttribute(rootAttri);//将刚创建的属性添加到根元素。
复制代码
Element
类操作:
Element root=doc.getRootElement();//获得根元素element
List allChildren=root.getChildren();//获得所有子元素的一个list
List namedChildren=root.getChildren("name");//获得指定名称子元素的list
Element child=root.getChild(“name”);//获得指定名称的第一个子元素
allChildren.remove(3);//删除第四个子元素
allChildren.removeAll(root.getChildren("jack"));//删除叫“jack”的子元素
root.removeChildren("jack");//便捷写法
allChildren.add(new Element("jane"));//加入
root.addContent(new Element(“jane”));//便捷写法
Element nameElement = new Element("name");//创建 name 元素
nameElement.addContent("kingwong");//将kingwong作为content添加到name元素
rootElement.addContent(nameElement);//将name元素作为content添加到根元素 getAttributeValue("name") 返回指定属性名字的值。如果没有该属性则返回null,有该属性但是值为空,则返回空字符串。
getChildText("childname") 返回指定子节点的内容文本值。
root.getChild("book").getChild("name").getText();
root.getChild("book").getChild("name").setText("dsgdghdgasg");
复制代码
解析 xml:
使用 Jdom
解析 xml
要导入 org.dom
的 jar
包
实例化一个合适的解析器对象
SAXBuilder builder = new SAXBuilder();
复制代码
构建一个文档对象 doc
Document doc = builder.build(new File("src\\dom.xml"));
复制代码
XML
文档输出:
XMLOutputter outputter=new XMLOutputter();
outputter.output(doc,new FileOutputStream("src\\dom.xml"));
复制代码
Dom4j
Dom4j
是一个 Java
的 XML API
,类似于 jdom
,用来读写 XML
文件的。它应用于 Java
平台,采用了 Java
集合框架并完全支持DOM
,SAX
和 JAXP
。
读取并解析 XML
文档:
读写 XML
文档主要依赖于 org.dom4j.io
包,其中提供 DOMReader
和SAXReader
两类不同方式,而调用方式是一样的。这就是依靠接口的好处。
// 从文件读取XML,输入文件名,返回XML文档
public Document read(String fileName) throws MalformedURLException, DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File(fileName));
return document;
}
复制代码
取得 Root
节点
public Element getRootElement(Document doc){
return doc.getRootElement();
}
复制代码
遍历 XML
树
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
// 枚举所有子节点
Element element = (Element) i.next();
}
for ( Iterator i = root.elementIterator(foo); i.hasNext();) {
// 枚举名称为foo的节点
Element foo = (Element) i.next();
}
// 枚举属性
for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {
Attribute attribute = (Attribute) i.next();
}
复制代码
递归也可以采用 Iterator
作为枚举手段,但文档中提供了另外的做法
public void treeWalk() {
treeWalk(getRootElement());
}
public void treeWalk(Element element) {
for (int i = 0, size = element.nodeCount(); i < size; i++) {
Node node = element.node(i);
if (node instanceof Element) {
treeWalk((Element) node);
} else { // do something....
}
}
}
复制代码
获取节点数量,包含自身。 这个方法所遍历出来的对象是多种的,node
,namespace
,text
等类型的。 if(element instanceof Element)
条件 element.nodeCount()==1
表示当前元素是子元素
创建 XML
public Document createDocument() {
Document document = DocumentHelper.createDocument();
Element root = document.addElement(root);
Element author1 =root.addElement(author).addAttribute(name, James)
.addAttribute(location, UK).addText(James Strachan);
Element author2 =root.addElement(author).addAttribute(name, Bob)
.addAttribute(location, US).addText(Bob McWhirter);
return document;
}
复制代码
字符串与 XML 的转换
有时候经常要用到字符串转换为 XML 或反之.
// XML转字符串
Document document = ...;
String text = document.asXML();
// 字符串转XML
String text = <name>James</name>
Document document = DocumentHelper.parseText(text);
复制代码
文件输出
一个简单的输出方法是将一个 Document 或任何的 Node 通过 write 方法输出。
FileWriter out = new FileWriter( foo.xml );
document.write(out);
// 美化输出或缩进格式,可以用XMLWriter类
public void write(Document document) throws IOException {
// 读取文件
FileWriter fileWriter = new FileWriter("src\\dom2.xml");
//OutputFormat xmlFormat = OutputFormat.createPrettyPrint();// 缩减型格式
OutputFormat xmlFormat =OutputFormat.createCompactFormat();//紧凑型格式
//format.setTrimText(false);//设置text中是否要删除其中多余的空格
xmlFormat.setEncoding("gb2312");// 设置编码
// 创建写文件方法
XMLWriter xmlWriter = new XMLWriter(fileWriter, xmlFormat);
// 写入文件
xmlWriter.write(document);
// 关闭
xmlWriter.close();
}
复制代码
评论