JavaXML解析的四种方法(连载)
1. xml简介
XML:指可扩展标记语言, Extensible Markup Language;类似HTML。XML的设计宗旨是传输数据,而非显示数据。
一个xml文档实例:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <company name="Tencent" address="深圳市南山区"> 3 <department deptNo="001" name="development"> 4 <employee id="devHead" position="minister">许刚</employee> 5 <employee position="developer">工程师A</employee> 6 </department> 7 <department deptNo="002" name="education"> 8 <employee position="minister" telephone="1234567">申林</employee> 9 <employee position="trainee">实习生A</employee> 10 </department> 11 </company>
第一行是 XML 声明。它定义 XML 的版本 (1.0) 和所使用的编码.
下一行描述文档的根元素:<company>开始,该根元素具有2个属性“name”,"address"。
最后一行定义根元素的结尾。</company>。
· XML 文档形成一种树结构
· XML 文档必须包含根元素。该元素是所有其他元素的父元素。
· XML 文档中的元素形成了一棵文档树。这棵树从根部开始,并扩展到树的最底端。
所有元素均可拥有子元素:
1 <root> 2 3 <child> 4 5 <subchild>.....</subchild> 6 7 </child> 8 9 </root>
父、子以及同胞等术语用于描述元素之间的关系。父元素拥有子元素。相同层级上的子元素成为同胞(兄弟或姐妹)。
1.1 节点
节点:XML文档中的所有节点组成了一个文档树(或节点树)。XML文档中的每个元素、属性、文本等都代表着树中的一个节点。树起始于文档节点,并由此继续伸出枝条,直到处于这棵树最低级别的所有文本节点为止,常用节点类型如下表所示:
节点类型 |
附加说明 |
实例 |
元素节点(Element) |
XML标记元素 |
<company>…</company> |
属性节点(Attribute) |
XML标记元素的属性 |
name=”Tencent” |
文本节点(Text) |
包括在XML标记中的文本段 |
工程师A |
文档类型节点(DocumentType) |
文档类型声明 |
﹤!DOCTYPE…﹥ |
注释节点Comment |
XmlComment类注释节点。 |
<!—文档注释-> |
(1) 节点关系
通过上面的XML文档,我们构建出如下树状文档对象模型:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <bookstore> 3 <book category="COOKING"> 4 <title lang="en">Everyday Italian</title> 5 <author>Giada De Laurentiis</author> 6 <year>2005</year> 7 <price>30.00</price> 8 </book> 9 <book category="CHILDREN"> 10 <title lang="en">Harry Potter</title> 11 <author>J K. Rowling</author> 12 <year>2005</year> 13 <price>29.99</price> 14 </book> 15 <book category="WEB"> 16 <title lang="en">Learning XML</title> 17 <author>Erik T. Ray</author> 18 <year>2003</year> 19 <price>39.95</price> 20 </book> 21 </bookstore>
再如上例xml文档:
例子中的根元素是 <bookstore>。文档中的所有 <book> 元素都被包含在 <bookstore> 中。<book> 元素有 4 个子元素:<title>、< author>、<year>、<price>。
(2)xml的特点
a). XML 的属性值须加引号。
· 与 HTML 类似,XML 也可拥有属性(名称/值的对)。
· 在 XML 中,XML 的属性值须加引号。
b). XML 文档必须有根元素.XML 文档必须有一个元素是所有其他元素的父元素。该元素称为根元素。
c). XML 标签对大小写敏感.
· XML 元素使用 XML 标签进行定义。
· XML 标签对大小写敏感。在 XML 中,标签 <Letter> 与标签 <letter> 是不同的。必须使用相同的大小写来编写打开标签和关闭标签。
d). XML 中的注释语法:
<!-- This is a comment -->
e). XML 元素 vs. 属性
1 <person sex="female"> 2 <firstname>Anna</firstname> 3 <lastname>Smith</lastname> 4 </person> 5 6 <person> 7 <sex>female</sex> 8 <firstname>Anna</firstname> 9 <lastname>Smith</lastname> 10 </person>
在第一行中,sex 是一个属性。在第7行中,sex 则是一个子元素。两个例子均可提供相同的信息。
2. xml 解析
xml解析方法有四种:
· DOM(JAXP Crimson 解析器):W3C为HTML和XML分析器制定的标准接口规范,基于树,可随机动态访问和更新文档的内容、结构、样式。
· SAX(simple API for XML):不是W3C的标准,而是由XML-DEV邮件列表成员于1998年为Java语言开发的一种基于事件的简单API。基于事件,逐行解析,顺序访问XML文档,速度快,处理功能简单。
· JDOM:鉴于DOM的低效率,而SAX又不能随机处理XML文档,Jason Hunter与Brett McLaughlin于2000年春天,开始创建一种能充分体现两者优势的API——JDOM(Java-based DOM,基于Java的DOM),它是一个基于Java的对象模型,树状结构,能使读取、操作和写入XML文档,比DOM更高效,比SAX更强大,但由于使用了大量的类而不使用接口导致灵活性降低。
· DOM4J:DOM4J是一个易用的,开源的库,用于XML,XPath,XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX,JAXP。它提供了大量的接口,因此比JDOM更具有灵活性。
2.1 DOM解析xml
DOM(Document Object Model文档对象模型),是W3C为HTML和XML分析器制定的标准接口规范。
特点:独立于语言,跨平台(可以在各种编程和脚本语言中使用),需要将整个文档读入内存,在内存中创建文档树,可随即访问文档中的特定节点,对内存的要求比较高,经过测试,访问速度相对于其他解析方式较慢,适用于简单文档的随即处理。
常用的节点属性:
属性 |
描述 |
nodeName |
结点名称 |
nodeValue |
结点内部值,通常只应用于文本结点 |
nodeType |
节点类型对应的数字 |
parentNode |
如果存在,指向当前结点的父亲结点 |
childNodes |
子结点列表 |
firstChild |
如果存在,指向当前元素的第一个子结点 |
lastChild |
如果存在,指向当前元素的最后一个子结点 |
previousSibling |
指向当前结点的前一个兄弟结点 |
nextSibling |
指向当前结点的后一个兄弟结点 |
attributes |
元素的属性列表 |
常用的节点方法:
操作类型 |
方法原型 |
描述 |
访问节点 |
getElementById(id) |
根据ID属性查找元素节点 |
getElementsByName(name) |
根据name属性查找元素集 |
|
getElementsByTagName(tagName) |
根据元素标记名称查找元素集 |
|
创建节点 |
createElement(tagName) |
创建元素节点 |
createTestNode(string) |
创建文本节点 |
|
createAttribute(name) |
创建属性节点 |
|
插入和添加节点 |
appendChild(newChild) |
添加子节点到目标节点上 |
insertBefore(newChild,targetChild) |
将newChild节点插入到targetChild节点之前 |
|
复制节点 |
CloneNode(bool) |
复制该节点,由bool确定是否复制子节点 |
删除和替换节点 |
removeChild(childName) |
删除由childName指定的节点 |
replaceChild(newChild,oldChild) |
用newChild替换oldChild |
|
属性节点操作 |
getAttribute(name) |
返回目标对象指定属性名称为name的属性值 |
setAttribute(name,value) |
修改目标节点指定属性名称为name的属性值为value |
|
removeAttribute(name) |
删除目标节点指定属性名称为name的属性 |
(1)读取本地xml文档解析为对象的步骤:
* 首先利用DocumentBuilderFactory创建一个DocumentBuilderFactory实例;然后利用DocumentBuilderFactory创建DocumentBuilder
//创建DocumentBuilderFactory工厂实例。 DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); //通过文档创建工厂创建文档创建器 DocumentBuilder dBuilder = dbfactory.newDocumentBuilder();
* 然后加载XML文档(Document) : 通过文档创建器DocumentBuilder的parse方法解析参数URL指定的XML文档,并返回一个Document 对象。
Document doc = dBuilder.parse(url);
* 然后获取文档的根结点(Element),
* 然后获取根结点中所有子节点的列表(NodeList),
* 然后使用再获取子节点列表中的需要读取的结点。
实例:第一种:Dom解析 (读取,增,删,改)
在实际开发中多思考,灵活运用,非是难事儿!,对于程序员来讲,精彩的代码是如何想出来的,远比看到精彩的代码更加令人期望!
books.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <books> <book typeId="1"> <bookId>001</bookId> <bookName>Maven实战</bookName> <bookPrice>51</bookPrice> <bookAuthor>陈晓斌</bookAuthor> </book> <book typeId="2"> <bookId>002</bookId> <bookName>谈谈支付宝底层体系架构的大家</bookName> <bookPrice>151</bookPrice> <bookAuthor>程立</bookAuthor> </book> <book TypeId="3"> <bookId>003</bookId> <bookName>预约死亡</bookName> <bookPrice>99</bookPrice> <bookAuthor>毕淑敏</bookAuthor> </book> <book TypeId="3"> <bookId>003</bookId> <bookName>预约死亡</bookName> <bookPrice>56</bookPrice> <bookAuthor>毕淑敏</bookAuthor> </book> </books>
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Test { /** * XML读取 * @throws Exception */ public static void xml() throws Exception{ //1.构建一个工厂 DocumentBuilderFactory dbFactory =DocumentBuilderFactory.newInstance(); //2.构建builder1 DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder(); //3.Document对象 //一般放相对路径就可以了,程序自动在项目下寻址 Document document = dbBuilder.parse("books.xml"); //4.XML解析 NodeList list =document.getElementsByTagName("book"); for (int i = 0; i < list.getLength(); i++) { Element item = (Element)list.item(i); String attribute=item.getAttribute("typeId"); String bookId=item.getElementsByTagName("bookId").item(0).getTextContent(); String bookName=item.getElementsByTagName("bookName").item(0).getTextContent(); String bookPrice=item.getElementsByTagName("bookPrice").item(0).getTextContent(); String bookAuthor=item.getElementsByTagName("bookAuthor").item(0).getTextContent(); System.out.println(bookId); System.out.println(bookName); System.out.println(bookPrice); System.out.println(bookAuthor); //System.out.println(attribute); System.out.println("-----------------"); } } /** * XML添加 * @throws Exception */ public static void insert() throws Exception{ //1.构建一个工厂 DocumentBuilderFactory dbFactory =DocumentBuilderFactory.newInstance(); //2.构建builder1 DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder(); //3.Document对象 Document document = dbBuilder.parse("books.xml"); //1.伪造内存中的节点,游离节点 Element book = document.createElement("book"); book.setAttribute("TypeId", "3"); Element bookId=document.createElement("bookId"); bookId.setTextContent("003"); Element bookName = document.createElement("bookName"); bookName.setTextContent("预约死亡"); Element bookPrice = document.createElement("bookPrice"); bookPrice.setTextContent("56"); Element bookAuthor = document.createElement("bookAuthor"); bookAuthor.setTextContent("毕淑敏"); book.appendChild(bookId); book.appendChild(bookName); book.appendChild(bookPrice); book.appendChild(bookAuthor); //1.将Book节点和整篇文档建立关联 document.getElementsByTagName("books").item(0).appendChild(book); //1.传输工厂 TransformerFactory transformerFactory = TransformerFactory.newInstance(); //2.传输器 Transformer transformer = transformerFactory.newTransformer(); Source source = new DOMSource(document); StreamResult result = new StreamResult("books.xml"); //3.传输方法 transformer.transform(source, result); System.out.println("save ok!"); } /** * XML修改 * @throws Exception */ public static void update() throws Exception{ //1.构建一个工厂 DocumentBuilderFactory dbFactory =DocumentBuilderFactory.newInstance(); //2.构建builder1 DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder(); //3.Document对象 Document document = dbBuilder.parse("books.xml"); //修改指定item的书的价格 //"E:/eclispsespace/JavaOOP-Day-09-0100/books.xml" Element book = (Element)document.getElementsByTagName("book").item(2); book.getElementsByTagName("bookPrice").item(0).setTextContent("99"); //传输工程 TransformerFactory transformerFactory = TransformerFactory.newInstance(); //传输器 Transformer transformer =transformerFactory.newTransformer(); Source source = new DOMSource(document); Result result = new StreamResult("books.xml"); transformer.transform(source, result); System.out.println("修改完毕!"); } /** * XML删除 * @throws Exception */ public static void delXml() throws Exception{ //1.构建一个工厂 DocumentBuilderFactory dbFactory =DocumentBuilderFactory.newInstance(); //2.构建builder1 DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder(); //3.Document对象 //一般放相对路径就可以了,程序自动在项目下寻址 Document document = dbBuilder.parse("books.xml"); Element book = (Element)document.getElementsByTagName("book").item(2); document.getElementsByTagName("books").item(0).removeChild(book); //传输工程 TransformerFactory transformerFactory = TransformerFactory.newInstance(); //传输器 Transformer transformer = transformerFactory.newTransformer(); Source source = new DOMSource(document); Result result =new StreamResult("books.xml"); transformer.transform(source, result); System.out.println("删除成功!"); } public static void main(String[] args) throws Exception { //xml();//读取 //insert();//增加 //update();//修改 delXml() ;//删除 } }
第二种:使用Dom4j解析XML
Dom4j:
Dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面还可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,所以可以知道dom4j无论在哪个方面都是非常出色的。如今可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这已经是必须使用的jar包,Hibernate也用它来读写文件。
所需jar包:dom4j-1.6.1.jar
实例图:
XML文件:
<?xml version="1.0" encoding="UTF-8"?> <people city="beijing"> <student name="milton" age="22"></student> <student name="lego" age="23"></student> <teacher name="bruce" age="27"></teacher> <teacher name="ziven" age="29"></teacher> </people>
对应entity:
People类:
Student类:
Teacher类:
TestXml类:
package cn.resolve.dom4j; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import cn.resolve.entity.People; import cn.resolve.entity.Student; import cn.resolve.entity.Teacher; /** * 测试使用dom4j解析XML * @author Zhang * */ public class TestXml { public static People xmlParse(String xmlPath){ File xmlFile = new File(xmlPath); System.out.println(xmlFile.getPath()); //判断文件是否存在 if (xmlFile.exists()) { SAXReader reader = new SAXReader(); People people = new People(); try { //读入文档流 Document document = reader.read(xmlFile); //获取根节点 Element root =document.getRootElement(); //创建两个对象集合 List<Student> students = new ArrayList<Student>(); List<Teacher> teachers = new ArrayList<Teacher>(); //拿到attribute属性的值 people.setCity(root.attributeValue("city")); //解析student节点 for (Iterator iterator = root.elementIterator("student");iterator.hasNext();) { Element eStudent= (Element)iterator.next(); Student student = new Student(eStudent.attributeValue("name"),Integer.parseInt(eStudent.attributeValue("age"))); //添加到集合 students.add(student); } //解析teacher节点 for (Iterator iterator= root.elementIterator("teacher");iterator.hasNext();) { Element eTeacher = (Element)iterator.next(); Teacher teacher = new Teacher(eTeacher.attributeValue("name"),Integer.parseInt(eTeacher.attributeValue("age"))); teachers.add(teacher); } people.setStudent(students); people.setTeacher(teachers); System.out.println("success!"); } catch (DocumentException e) { e.printStackTrace(); } return people; }else { System.out.println("file is not exist!"); return null; } } public static void main(String[] args) { String xmlpath = "src/people.xml"; //解析people.xml People people =xmlParse(xmlpath); System.out.println("file full path is xmlpath "); List<Teacher> teachers = new ArrayList<Teacher>(); List<Student> students = new ArrayList<Student>(); System.out.println(people.getCity()); //处理解析结果 for (Student s : students) { System.out.println("学生姓名/t/t年龄"); System.out.println(s.getName()+":"+s.getAge()); } for (Teacher t: teachers) { System.out.println("教师姓名/t/t年龄"); System.out.println(); } } }
posted on 2018-05-30 15:01 技术之路永无止境~ 阅读(1091) 评论(0) 编辑 收藏 举报