本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看<活动链接>
在实际工作中,对 XML 文件的操作是非常常见的,在此将对 XML 文件的解析展开讨论,与大家分享一下,希望以后工作中遇到能够快速上手。
XML解析
在 xml 文件中由于更多的是描述信息的内容,所以在得到一个xml文档之后应该利用程序按照里面元素的定义名称取出对应的内容,这一过程就称为xml解析。
解析xml文件的4种方式:
DOMSAXJDOMDOM4J
文档对象模型(DOM)
DOM---对象化的XML数据接口
它定义了XML文档的逻辑结构,给出了一种访问和处理XML文档的方法。利用DOM,程序开发人员可以动态地创建文档,遍历文档结构,添加、修改、删除文档内容,改变文档的显示方式等等。
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();
}