xml知识(三)

XML解析:
一、DOM解析
    DOM 是 W3C 处理 XML 的标准 API,它是许多其它与 XML 处理相关的标准的基础,不仅是 Java,其它诸如 Javascript,PHP .NET 等等语言都实现了该标准, 成为了应用最为广泛的 XML 处理方式。当然,为了能提供更多更加强大的功能,Java 对于 DOM 直接扩展工具类有很多,比如很多 Java 程序员耳熟能详的 DOM4J,JDOM 等等, 它们基本上属于对 DOM 接口功能的扩充,保留了很多 DOM API 的特性,许多原本的 DOM 程序员甚至都没有任何障碍就熟练掌握了另外两者的使用,直观、易于操作的方式使它深受广大 Java 程序员的喜爱。
  1.XML DOM简介
    1.1DOM的分类
    DOM 是 W3C(万维网联盟) 的推荐标准。
    DOM 定义了访问诸如 XML 和 XHTML 文档的标准。
    “W3C 文档对象模型(DOM)是一个使程序和脚本有能力动态地访问和更新文档的内容、结构以及样式的平台和语言中立的接口。”
    W3C DOM 被分为 3 个不同的部分/级别(parts / levels):
1)核心 DOM
    用于任何结构化文档的标准模型(提供了同时操作HTML文档和XML文档的公共属性和方法)
2)XML DOM
    用于XML文档的标准模型(定义了所有 XML 元素的对象和属性,以及访问它们的方法(接口)针对XML文档提供的专用的属性和方法)
3)HTML DOM
    用于HTML文档的标准模型(定义了所有HTML元素的对象和属性,以及访问它们的方法(接口)针对HTML文档提供的专用的属性和方法)
DOM 定义了所有文档元素的对象和属性,以及访问它们的方法(接口)。


   1.2什么是XML DOM?
XML DOM是XML Document Object Model的缩写,即XML文档对象模型。XML DOM定义了访问和处理XML文档的标准方法。
用于 XML 的标准对象模型
    用于 XML 的标准编程接口
    中立于平台和语言
    W3C 的标准
换句话说,XML DOM是用于获取、更改、添加或者删除XML元素的标准。
   1.3处理方式:
     1)DOM 将 XML 文档作为一个树形结构,而树叶被定义为节点,XML文档中的每个成分都是一个节点。
将XML整个作为类似树结构的方式读入内存中以便操作及解析,因此支持应用程序对XML数据的内容和结构进行修改,但是同时由于其需     要在处理开始时将整个 XML 文件读入到内存中去进行分析,因此其在解析大数据量的 XML 文件时会遇到类似于内存泄露以及程序崩的风险
   根据DOM,XML被文档视为一种树结构。这种树结构被称为节点树。文档中的每个成分都是一个节点(Node)。可通过这棵树访问所有节点 。可     以修改或删除它们的内容,也可以创建新的元素。
     2)DOM 是这样规定的:
整个文档是一个文档节点(Document)
每个 XML 标签是一个元素节点(Element)
包含在 XML 元素中的文本是文本节点(TextNode)
每一个 XML 属性是一个属性节点(AttributeNode)
注释属于注释节点(CommentNode)
注:文本总是存储在文本节点中,在 DOM 处理中一个普遍的错误是,认为元素节点包含文本。不过,元素节点的文本是存储在文本节点    中的。在这个例子中:<year>2005</year>,元素节点 <year>,拥有一个值为 "2005" 的文本节点。"2005" 不是 <year> 元素的值!
   空格也属于文本节点。
     3)父、子和同级节点
  节点树中的节点彼此之间都有等级关系。
父、子和同级节点用于描述这种关系。父节点拥有子节点,位于相同层级上的子节点称为同级节点(兄弟或姐妹)。
在节点树中,顶端的节点成为根节点
  根节点之外的每个节点都有一个父节点
  节点可以有任何数量的子节点
      叶子是没有子节点的节点
  同级节点是拥有相同父节点的节点
     4)DOM节点类型(包括html)
DOM中节点类型(NodeType)有多种(12),以下列出常见的5种,每种类型的节点都有一个值为1到12之间的有名常数表示。
通过获取节点(Node),调用其方法,我们可以得到其NodeType,NodeNAME,NodeValue。


节点类型 描述(有名常数:NoteType)        NodeName的返回值        NodeValue的返回值
Document 整个文档,DOM 树的根节点(9) #document(固定) null
Element 元素节点(1) 元素的名称 null
Attr 属性节点(2) 属性的名称 属性的值
Text 文本节点(3) #text 文本节点内容
comment 注释节点(8) #comment 注释节点的内容
......
     5)JDK中的dom操作的API
使用java语言解析xml文档:
   JDK 中的 DOM API 遵循 W3C DOM 规范,其中 org.w3c.dom 包提供了 Document、DocumentType、Node、NodeList、Element 等接口, 这些接口均是访问 DOM 文档所必须的。我们可以利用这些接口创建、遍历、修改 DOM 文档。(xml dom)
org.w3c.dom包下,Node为超级接口,document,element等为子接口。
常用方法:
getAttributes()
getChildNodes():包括文本子节点
getFirstChild()
getLastChild()
getNextSibling()
getNodeName()
getNodeValue()
getNodeType()
getParentNode()...
appendChild(Node newChild)...添加到此节点的子节点末尾,父节点调用
removeChild(Node oldChild)
insertBefore(Node newChild, Node refChild)父节点调用
appendChild(Node node);//child:指的是直接子节点
insertBefore(Node newChild,Node refChild);
removeChild(Node node);
replaceChild(Node newChild, Node oldChild);
getTextContent()
getElementsByTagName();-----document--element
getDocumentElement()
createElement()
createTextNode()
适用范围:
小型 XML 文件解析、需要全解析或者大部分解析 XML、需要修改 XML 树内容以生成自己的对象模
使用方法:
javax.xml.parsers包中的DoumentBuilder 和 DocumentBuilderFactory用于解析XML 文档生成对应的DOM Document对象。
//获取Dom解析工厂实例
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//获取Dom文档创建器
DocumentBuilder builder = factory.newDocumentBuilder();
//1.获取document对象,代表整个xml文档书
Document document = builder.parse(new File("xml文件路径"));


进行解析或者增删修改操作------
document.getElementsByTagName("元素名称");getDocumentElement()..........
book.xml
1.查看各个节点(document,element,attr,text,comment)的noteType,noteName,noteValue
2.空格等文本内容
--------------------------------
//2.创建document对象,创建一个空白文档
Document document = builder.newDocument();
添加子节点:
document.createElement("name");
createAttribute("name");
createTextNode("value");
appendChild();
对文档内容进行操作(增删修改)之后,持久化保存到文件中:
   javax.xml.transform.dom 和 javax.xml.transform.stream 包中 DOMSource 类和 StreamSource 类,用于将更新后 的DOM 文档写入 XML 文件
document.setXmlStandalone(true);
//javax.xml.transform.TransformerFactory
TransformerFactory factory = TransformerFactory.newInstance();
Transformer form = factory.newTransformer();
form.setOutputProperty(OutputKeys.INDENT, "yes");
form.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
form.setOutputProperty(OutputKeys.STANDALONE, "yes");
form.transform(new DOMSource(document对象), new StreamResult(new File("xml文件路径")));


或者使用crimson.jar中的类:org.apache.crimson.tree.XmlDocument,有时会发生冲突
((XmlDocument)document).write(new FileOutputStream("xml文件路径"));


在java中,原生解析xml文档的方式有两种,分别是:Dom解析和Sax解析,Dom解析功能强大,可增删改查,操作时会将xml文档以文档对     象的方式读取到内存中,因此适用于小文档,Sax解析是从头到尾逐行逐个元素读取内容,修改较为不便,但适用于只读的大文档。


二、SAX解析
SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。
它不像DOM那样是W3C的推荐标准。它是由XML-DEV邮件列表的成员开发维护,由David Megginson领导(david@megginson.com)的一个Public Domain软件。SAX是一个彻底的自由软件,它的作者放弃了对它的所有权利,并且它也被许可用于任何目的
到现在为止SAX的版本已经发展到2.0。在这个最新版本中增加了对名称空间(Namespaces)的支持。
SAX并不是一个实际可以使用的XML文档解析器,而是其他兼容SAX的解析器要实现的接口和帮助类的集合。如果你想使用SAX的话,你必须满足下面的要求:
1.系统中包含Java 1.1 或者更高版本。
2.在Java classpath中包含进你的SAX类库。
3.在Java classpath中包含进你要使用的兼容SAX的XML解析器类库。
在SAX API中有两个包,org.xml.sax和org.xml.sax.helper。其中org.xml.sax中主要定义了SAX的一些基础接口,如XMLReader、ContentHandler、ErrorHandler、DTDHandler、EntityResolver等。而在org.xml.sax.helper中则是一些方便开发人员使用的帮助类,如缺省实现所有处理器接口的帮助类DefaultHandler、方便开发人员创建XMLReader的XMLReaderFactory类等等
JDK中sax解析API,Sun公司提供的,org.xml.sax.*
Sax特征:
与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。
Sax采用事件驱动的方式解析文档。简单点说,如同在电影院看电影一样,从头到尾看一遍就完了,不能回退(Dom可来来回回读取),Sax解析是按照xml文件的顺序一步一步的逐行来解析,在看电影的过程中,每遇到一个情节,一段泪水,一次擦肩,你都会调动大脑和神经去接收或处理这些信息,同样,在Sax的解析过程中,读取到文档开头、结尾,元素的开头和结尾都会触发一些回调方法,你可以在这些回调方法中进行相应事件处理。这四个方法是:startDocument() 、 endDocument()、 startElement()、 endElement。此外,光读取到节点处是不够的,我们还需要characters()方法来仔细处理元素内包含的内容。将这些回调方法集合起来,便形成了一个类,这个类也就是我们需要的触发器,在触发器中,首先开始读取文档,然后开始逐个解析元素,每个元素中的元素文本内容(空格不能忽略)会返回到characters()方法。触发器继承自DefaultHandler。
适用范围:
大型 XML 文件解析、只需要部分解析或者只想取得部分 XML 树内容。由于SAX分析器实现简单,对内存要求比较低,(SAX不必将整个XML文档加载到内存当中,因此它占据内存要比DOM小), 因此实现效率比较高。对于大型的XML文档来说,通常会用SAX而不是DOM。
并且对于那些只需要访问XML文档中的数据而不对文档进行更改的应用程序来说,SAX分析器更为合适。
使用方法:
//获取sax解析器工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//获取sax解析对象
SAXParser saxParser = factory.newSAXParser();
//使用指定DefaultHandler解析xml文档
saxParser.parse(new File("src/com/briup/xml/day3/book.xml"), new DefaultHandler(){"匿名内部类"});


     DefaultHandler中常用的方法:
startDocument():文档开始调用的方法,遇到<?xml...?>时
endDocument():文档结束调用的方法。
startElement(String uri, String localName, String qName, Attributes attributes):遇到元素开始标签"<"会调用的方法。
uri:命名空间地址,需要打开支持命名空间特性;
localName:本地名称,不包含命名空间与前缀,如果没有命名空间且支持命名空间的特性没有打开,值为空字符串。    factory.setNamespaceAware(true);打开命名空间
qName:带有前缀的限定名,如果使用的是默认命名空间,则一样为本地名,attributes:当前元素属性的集合
Attributes有方法:getQName(i),getValue(i):遍历时获取属性名与属性值。
endElement(String uri, String localName, String qName):遇到结束标签会调用的方法:"</" @单标签
characters(char[] ch, int start, int length):每次遇到字符就会调用此方法,空格也是字符,也会调用
ch是传回来的字符数组,其包含从开始解析到当前这一段文本,包含着所有的元素内容
start和length分别是当前文本在数组中的开始位置和结束位置
String有构造器:
String(char[] value,int offset,int count);
value - 作为字符源的数组。
offset - 初始偏移量。
count - 长度。


使用sax解析创建xml文档:
//1.创建SAXTransformerFactory实例
SAXTransformerFactory sff = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
//2.创建TransformerHandler实例
TransformerHandler handler = sff.newTransformerHandler();
//3.通过handler对象获取javax.xml.transform.Transformer对象
Transformer tf = handler.getTransformer();
//4.tf对象用来设置结果格式
tf.setOutputProperty(OutputKeys.INDENT, "yes");
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tf.setOutputProperty(OutputKeys.STANDALONE, "yes");
//5.通过handler对象与result对象关联,将xml信息写入文件
handler.setResult(new StreamResult(new File("要保存的xml文件路径")));
//6.调用handler的方法创建xml文件内容
handler.startDocument();startElement();characters();endElement();endDocument();
//需使用 org.xml.sax.helpers.AttributesImpl类对象,addAttribute();clear();


例:handler.startDocument();
AttributesImpl attrs = new AttributesImpl();
handler.startElement("","","books", attrs);
attrs.addAttribute("","","bid","","001");
handler.startElement("","","book", attrs);
handler.characters("java核心技术I".toCharArray(), 0, "java核心技术I".length());
handler.endElement("","","book");
attrs.clear();
attrs.addAttribute("","","bid","","002");
handler.startElement("","","book", attrs);
handler.characters("java核心技术II".toCharArray(), 0, "java核心技术II".length());
handler.endElement("","","book");
handler.endElement("","","books");
handler.endDocument();


三、dom4j

DOM4J 是一个非常优秀的Java XML API,具有性能优异、功能强大和极端易于使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML。
DOM4J使用起来非常简单。只要你了解基本的XML-DOM模型,就能使用;Dom:把整个文档作为一个对象
DOM4j的主要接口定义在org.dom4j包里:
Attribute 定义了 XML 的属性。
Branch 指能够包含子节点的节点。如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为
CDATA 定义了 XML CDATA 区域
CharacterData 是一个标识接口,标识基于字符的节点。如CDATA,Comment, Text.
Comment 定义了 XML 注释的行为
Document 定义了XML 文档
DocumentType 定义 XML DOCTYPE 声明
Element 定义XML 元素
ElementHandler 定义了Element 对象的处理器
ElementPath 被 ElementHandler 使用,用于取得当前正在处理的路径层次信息
Entity 定义 XML entity
Node 为dom4j中所有的XML节点定义了多态行为
NodeFilter 定义了在dom4j 节点中产生的一个滤镜或谓词的行为(predicate)
ProcessingInstruction 定义 XML 处理指令
Text 定义 XML 文本节点
Visitor 用于实现 Visitor模式
XPath 在分析一个字符串后会提供一个 XPath 表达式
接口之间的继承关系如下:
interface java.lang.Cloneable
   interface org.dom4j.Node
          interface org.dom4j.Attribute


  interface org.dom4j.Branch
                 interface org.dom4j.Document
                 interface org.dom4j.Element
          interface org.dom4j.CharacterData
                 interface org.dom4j.CDATA
                 interface org.dom4j.Comment
                 interface org.dom4j.Text
          interface org.dom4j.DocumentType
          interface org.dom4j.Entity
          interface org.dom4j.ProcessingInstruction
注:DOM4j的Node.nodevalue()方法的返回类型与dom是一致的。(1--9)
//获取解析器
SAXReader saxReader = new SAXReader();
//获取dom4j的document对象(org.dom4j.Document)
Document document = saxReader.read(new File(Path));
对document的操作:
Element root = document.getRootElement();//获取根元素
对于元素的操作:
获取所有子元素:
方法1:
List<Element> childList = root.elements();//取到所有子元素(直接子元素)
方法2:
Iterator it = root.elementIterator();(it.hasNext(),it.next())
获取所有的属性:
方法1:
List<Attribute> atts = childList.get(index).attributes();
方法2:
Iterator attrs = childList.attributeIterator();(it.hasNext(),it.next())
对于属性的操作:
getName();getValue();
对节点(Node)的操作:
getName(),getNodeType(),getText(),getStringValue()(包含子节点的子节点...的所有的文本值)...
nodeIterator(),node(i),nodeCount()


使用dom4j将xml文档转换为字符串,将字符串转换为xml
xml转字符串
String text = document.asXML();
System.out.println(text);
字符串转xml
String xmlText = "<student><name>zhangsan</name></student>";
Document docxml = DocumentHelper.parseText(xmlText);
  DOM4j操作xml文档
创建document或者通过DocumentHelper
Document document = DocumentFactory.getInstance().createDocument();//DocumentHelper.createDocument()
添加元素、文本、注释、属性
Element root = document.addElement("students");
root.addText("123");
root.addComment("学生信息:");
root.addAttribute(String attrName,String attrValue);
其他方法:remove(Element element);setText(String text)


文件输出,保存到物理文件中:
1、一个简单的输出方法是将一个Document或任何的Node通过write方法输出:
FileWriter fw = new FileWriter("src/com/briup/xml/day3/dom4j17/bookDC1.xml");
document.write(fw);
fw.close();
2.使用org.dom4j.io.OutputFormat类格式化输出:借助于org.dom4j.io.XMLWriter、org.dom4j.io.OutputFormat
2.1简单输出紧凑的样式(与1一致):
FileWriter fw3 = new FileWriter("src/com/briup/xml/bookDC3.xml");
OutputFormat of2 = OutputFormat.createCompactFormat();
of2.setEncoding("UTF-8");//默认UTF-8
XMLWriter xw2 = new XMLWriter(fw3,of2);
xw2.write(document);
xw2.flush();
xw2.close();
2.2美化输出
FileWriter fw2 = new FileWriter("src/com/briup/xml/bookDC2.xml");
OutputFormat of = new OutputFormat();
of.setEncoding("utf-8");
of.setIndent(true);
of.setNewlines(true);
XMLWriter xw = new XMLWriter(fw2,of);
xw.write(document);
xw.flush();
xw.close();
2.3便捷美化输出:
FileWriter fw4 = new FileWriter("src/com/briup/xml/bookDC4.xml");
OutputFormat of3 = OutputFormat.createPrettyPrint();
XMLWriter xw3 = new XMLWriter(fw4,of3);
xw3.write(document);
xw3.flush();
xw3.close();





























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值