发表新主题 回复该帖子
主题:[转]用JDK自带的包来解析XML文件(DOM+xpath)
唧唧
帖子档案  楼主 [转]用JDK自带的包来解析XML文件(DOM+xpath)   Post by : 2009-09-15 23:03:55.0
  • 幼儿园
  • 幼儿园
  • UID:3
  • 主题:342
  • 帖子:781
  • 加为好友 加为好友    发送短信 发送短信

DOM编程不要其它的依赖包,因为JDK里自带的JDK里含有的上面提到的org.w3c.dom、org.xml.sax 和javax.xml.parsers包就可以满意条件了。
(1)org.w3c.dom W3C推荐的用于XML标准规划文档对象模型的接口。
(2)org.xml.sax 用于对XML进行语法分析的事件驱动的XML简单API(SAX)
(3)javax.xml.parsers解析器工厂工具,程序员获得并配置特殊的特殊语法分析器。

先来写一个xml文件(DTD文件请参阅XML DTD那篇博文 2F):

   xhtml代码
  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <!DOCTYPE book SYSTEM "D:\workspace\XML\WebRoot\WEB-INF\book.dtd"> 
  3. <book> 
  4. <bookname name="XML详解" font="GB2312"></bookname> 
  5. <authors> 
  6. <author name="张孝祥" sex="男" age="45"></author> 
  7. <author name="王勇" sex="男" age="35"></author> 
  8. <author name="王波" sex="男" age="30"></author> 
  9. </authors> 
  10. <price value="¥55"></price> 
  11. <publishdate> 
  12. <value>2009-08-18</value> 
  13. </publishdate> 
  14. </book> 

再来写解析xml文件的java文件:

   java代码
  1. package com.xml.jdk;  
  2.  
  3. import java.io.FileInputStream;  
  4. import java.io.FileNotFoundException;  
  5. import java.io.IOException;  
  6.  
  7. import javax.xml.parsers.DocumentBuilder;  
  8. import javax.xml.parsers.DocumentBuilderFactory;  
  9. import javax.xml.parsers.ParserConfigurationException;  
  10. import javax.xml.xpath.XPath;  
  11. import javax.xml.xpath.XPathConstants;  
  12. import javax.xml.xpath.XPathExpressionException;  
  13. import javax.xml.xpath.XPathFactory;  
  14.  
  15. import org.w3c.dom.Document;  
  16. import org.w3c.dom.NamedNodeMap;  
  17. import org.w3c.dom.Node;  
  18. import org.w3c.dom.NodeList;  
  19. import org.xml.sax.SAXException;  
  20.  
  21. public class XPathForXml {  
  22.     public void parseXMLWithJdk(){       
  23.         try {  
  24.             //读取book.xml到内存  
  25.             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
  26.             DocumentBuilder dbd = dbf.newDocumentBuilder();  
  27.             Document doc = dbd.parse(new FileInputStream("D:\\workspace\\XML\\WebRoot\\WEB-INF\\book.xml"));  
  28.  
  29.             //通过XML获得book的authors的author子节点列表  
  30.             XPathFactory f = XPathFactory.newInstance();  
  31.             XPath path = f.newXPath();  
  32.             NodeList authors= (NodeList) path.uate("book/authors/author", doc,XPathConstants.NODESET);  
  33.             System.out.println(authors.getLength());  
  34.             //遍历取到的元素  
  35.             if(authors!=null){  
  36.                 for(int i=0;i<authors.getLength();i++){  
  37.                     Node author    = authors.item(i);  
  38.                     int n = i + 1;  
  39.                     System.out.print(n+".  名字:"+author.getNodeName());                         
  40.                     System.out.println();  
  41.                 }  
  42.             }  
  43.                  
  44.             //获得book的authors的第一个子节点,注意NODESET和NODE的区别  
  45.             Node author= (Node) path.uate("book/authors/author", doc,XPathConstants.NODE);  
  46.             System.out.println("  名称:"+author.getNodeName());  
  47.             System.out.println("  内容:"+author.getTextContent());//如果存在内容则返回内容,不存在则返回空  
  48.             //获取节点的属性  
  49.             NamedNodeMap attr =  author.getAttributes();  
  50.             System.out.println("  该节点的属性个数"+attr.getLength());  
  51.             //遍历元素的属性  
  52.             if(attr!=null){  
  53.                 for(int i=0;i<attr.getLength();i++){  
  54.                 int n = i + 1;  
  55.                     System.out.print("   属性"+n+"   名称:"+attr.item(i).getNodeName());  
  56.                     System.out.print("   值:"+attr.item(i).getNodue());  
  57.                     System.out.print("   类型:"+attr.item(i).getNodeType());  
  58.                     System.out.println();  
  59.                 }  
  60.             }  
  61.  
  62.         } catch (ParserConfigurationException e) {  
  63.             e.printStackTrace();  
  64.         } catch (FileNotFoundException e) {  
  65.             e.printStackTrace();  
  66.         } catch (SAXException e) {  
  67.             e.printStackTrace();  
  68.         } catch (IOException e) {  
  69.             e.printStackTrace();  
  70.         } catch (XPathExpressionException e) {  
  71.             e.printStackTrace();  
  72.         }  
  73.     }  
  74.  
  75.     public static void main(String[] args) {  
  76.         new XPathForXml().parseXMLWithJdk();  
  77.     }  
  78.  

下面对DOM读取XML的代码进行讲解:
(1)得到DOM解析器的工厂实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
得到javax.xml.parsers.DocumentBuilderFactory;类的实例就是我们要的解析器工厂

(2)从DOM工厂获得DOM解析器
DocumentBuilder dbd = domfac.newDocumentBuilder();
通过javax.xml.parsers.DocumentBuilderFactory实例的静态方法newDocumentBuilder()得到DOM解析器

(3)把要解析的XML文档转化为输入流,以便DOM解析器解析它
InputStream is=new FileInputStream("D:\\workspace\\XML\\WebRoot\\WEB-INF\\book.xml");
InputStream是一个接口。

(4)解析XML文档的输入流,得到一个Document
Document doc=dombuilder.parse(is);
由XML文档的输入流得到一个org.w3c.dom.Document对象,以后的处理都是对Document对象进行的

签名
 ★★★★★★★★
 纵里寻她千百度,蓦然回首,那人却在,灯火阑珊处!
 MyBlog :http://blog.javawind.net
返回页面顶部  

唧唧
2F Re:[转]用JDK自带的包来解析XML文件(DOM+xpath)   Post by : 2009-09-15 23:10:13.0
  • 幼儿园
  • 幼儿园
  • UID:3
  • 主题:342
  • 帖子:781
  • 加为好友 加为好友    发送短信 发送短信

DTD文档类型定义(Document Type Definition)

DTD 是一套关于标记符的语法规则。它是XML1.0版规格得一部分,是XML文件的验证机制,属于XML文件组成的一部分。

XML文件提供应用程序一个数据交换的格式,DTD正是让XML文件能够成为数据交换的标准,因为不同的公司只需定义好标准的DTD,各公司都能够依照DTD建立XML文件,并且进行验证,如此就可以轻易的建立标准和交换数据,这样满足了网络共享和数据交互。

DTD文件是一个ASCII的文本文件,后缀名为.dtd。

现在先写一个DTD文件book.dtd:

   xhtml代码
  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <!ELEMENT book (bookname,authors,price,publishdate,comment*) > 
  3. <!ELEMENT bookname EMPTY > 
  4. <!ATTLIST bookname name CDATA #REQUIRED > 
  5. <!ATTLIST bookname font CDATA "GB2312" > 
  6. <!ATTLIST bookname size CDATA "3" > 
  7. <!ATTLIST bookname color CDATA "black" > 
  8. <!ELEMENT authors (author+) > 
  9. <!ELEMENT author EMPTY > 
  10. <!ATTLIST author name CDATA #REQUIRED > 
  11. <!ATTLIST author sex (男|女) "男" > 
  12. <!ATTLIST author age CDATA  #IMPLIED > 
  13. <!ATTLIST author tel CDATA #IMPLIED > 
  14. <!ELEMENT price (value*) > 
  15. <!ATTLIST price value CDATA #IMPLIED > 
  16. <!ELEMENT value (#PCDATA) > 
  17. <!ELEMENT publishdate (value*) > 
  18. <!ATTLIST publishdate value CDATA #IMPLIED > 
  19. <!ELEMENT comment (value*,list*,map*) > 
  20. <!ATTLIST comment value CDATA #IMPLIED > 
  21. <!ELEMENT list (value+) > 
  22. <!ELEMENT map (key+) > 
  23. <!ELEMENT key EMPTY > 
  24. <!ATTLIST key name CDATA #REQUIRED> 
  25. <!ATTLIST key value CDATA #REQUIRED> 

以上 DTD 解释如下:

<?xml version (第一行)是对文件的声明

!ELEMENT note (第二行)定义 book 元素有四个元素:"bookname,authors,price,publishdate,comment",其中comment后面的“*”表示这个元素可以有0或多个,如果是“?”表示0或1个,如果是“+”表示1或多个,而如果元素后面什么标记也没有,则该元素在XML文件中有且仅有一个,最后声明一下这些元素的顺序是固定的,颠倒顺序会导致错误。

!ELEMENT bookname (第三行)定义 bookname  元素为 "EMPTY" 类型

声明一个元素
在 DTD 中,XML 元素通过元素声明来进行声明。元素声明使用下面的语法:
<!ELEMENT 元素名称类别>
或者
<!ELEMENT 元素名称 (元素内容)>
1.空元素
空元素通过类别关键词EMPTY进行声明:
<!ELEMENT 元素名称 EMPTY>
2.只有 PCDATA 的元素
只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:
<!ELEMENT 元素名称 (#PCDATA)>
3.带有任何内容的元素
通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:
<!ELEMENT 元素名称 ANY>
4.带有子元素(序列)的元素
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:
<!ELEMENT 元素名称 (子元素名称 1)>
或者
<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>
5.相同的元素至少出现一次的声明
语法格式为:
<!ELEMENT element-name (child-name+)> 
例:
<!ELEMENT note (message+)>
例中的+是指子元素message必须在被包含的note元素里出现一次或者多次
6.相同的元素不出现或者多次出现的声明
语法格式为:
<!ELEMENT element-name (child-name*)>
例:
<!ELEMENT note (message*)>
例中的*是指子元素message能够在被包含的note元素里不出现或者出现多次

<!ATTLIST bookname name CDATA #REQUIRED > (第四行)定义 bookname 的属性name。

声明属性
属性声明拥使用下列语法:
<!ATTLIST 元素名称属性名称属性类型默认值>
以下是属性类型的选项:
1.类型 描述
CDATA 值为字符数据 (character data)
(en1|en2|..) 此值是枚举列表中的一个值
ID 值为唯一的 id
IDREF 值为另外一个元素的 id
IDREFS 值为其他 id 的列表
NMTOKEN 值为合法的 XML 名称
NMTOKENS 值为合法的 XML 名称的列表
ENTITY 值是一个实体
ENTITIES 值是一个实体列表
NOTATION 此值是符号的名称
xml: 值是一个预定义的 XML 值
默认值参数可使用下列值:
2.值 解释
值属性的默认值
#REQUIRED 属性值是必需的
#IMPLIED 属性不是必需的
#FIXED value 属性值是固定的
规定一个默认的属性值
DTD:
<!ELEMENT bookname EMPTY >
<!ATTLIST bookname name CDATA #REQUIRED >
<!ATTLIST bookname font CDATA "GB_2312" >

合法的 XML:
<bookname name="XML详解" font="宋体"/>
在上面的例子中,"bookname" 被定义为带有 CDATA 类型的 "name" 属性和font属性的空元素。如果font没有被设定,其默认值为GB_2312 。

<!ATTLIST author sex (男|女) "男" >带有默认值来约束,属性sex的取值只能是男或女,其他值都会出错。约束属性值!

其他代码与上面四行相似,请参照上面对声明元素和声明属性的讲解,还有一点值得注意的同一个元素不能同时声明多个,如文件中常用到的17.<!ELEMENT value (#PCDATA) >,声明一个即可共用。

现在将书写基于该DTD文件的XML文件 book.xml:

   xhtml代码
  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <!DOCTYPE book SYSTEM "book.dtd"> 
  3. <book> 
  4.  <bookname name="XML详解" font="GB2312"></bookname> 
  5.  <authors> 
  6.   <author name="张孝祥" sex="男" age="45"></author> 
  7.   <author name="王勇" sex="男" age="35"></author> 
  8.   <author name="王波" sex="男" age="30"></author> 
  9.  </authors> 
  10.  <price value="¥55"></price> 
  11.  <publishdate> 
  12.   <value>2009-08-18</value> 
  13.  </publishdate> 
  14.  <comment value="知名教师精讲"> 
  15.   <list> 
  16.    <value>传智播客</value> 
  17.    <value>尚学堂</value> 
  18.    <value>东方标准</value> 
  19.   </list> 
  20.   <map> 
  21.    <key name="传智播客" value="张孝祥"/> 
  22.    <key name="尚学堂" value="王勇"/> 
  23.    <key name="东方标准" value="王波"/>    
  24.   </map> 
  25.  </comment> 
  26. </book> 

子元素/属性

要表示某一个元素的特性时,是该用子元素表示,还是使用属性表示呢,下面提供一些原则:

1.特性中还包含着子结构,如comment元素的list特性,list还包含子结构value,此时用子元素。
2.特性有多个,如authors的author特性,它含有多个author,此时用子元素。
3.经常改变的特性,此时用子元素。
4.比较重要的特性用子元素表示,说明性的或者辅助性的特性用属性表示。
5.需要DTD来做严格检查的,用子元素。如要对性别进行约束,则sex特性用子元素表示。

签名
 ★★★★★★★★
 纵里寻她千百度,蓦然回首,那人却在,灯火阑珊处!
 MyBlog :http://blog.javawind.net
返回页面顶部  


CopyRight © 2008-2009 JavaWind.Net Studio All Rights Reserved
Powered By JWind.BBS Vesion 1.0.0 Beta1 Processed in 22 ms,0 (Queries)  Gzip enabled

WAP - 清除Cookies - 联系我们 - JavaWind.Net Studio - Archiver - TOP Valid XHTML 1.0 Transitional Valid CSS! 粤ICP备07511478号