在实际工作中,对 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();//获得根元素elementList allChildren=root.getChildren();//获得所有子元素的一个listList namedChildren=root.getChildren("name");//获得指定名称子元素的listElement 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();// 字符串转XMLString 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();}
复制代码
评论