免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7118 | 回复: 6
打印 上一主题 下一主题

XML概念和应用(二)分析XML [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-08-11 23:14 |只看该作者 |倒序浏览
  首先得向大家申明,在分析XML这篇里,我原版引用了zlzj2010仁兄的大作,原因是想让大家重复读一个例子,起到了两遍印象的作用。当然这有剽窃的嫌疑,不过能更好的说明XML的概念和应用,只好担起这个罪名。这里先向“zlzj2010”仁兄谢罪,版主如果认为不适,请删掉他。
       第二章    分析XML
2.2.1为什么要分析?
  首先我们生成XML的目的不是要将XML文档显示在计算机的屏幕上,它是作为一个标准的消息结构存在的,接受消息的一方根据需要取出XML文档是节点所标识的数据,然后再将这些数据作相应的处理,这才是XML文档存在的意义。
  因此,之所以要分析XML是要从XML文档中获取节点数据。这,就是原因。

2.2.2 分析的方法
一、        DOM(文档对象模型)方法:
W3C已于2000年11月13日推出了规范DOM level 2,DOM是用于访问和更新文档的接口,它与语言无关。因而可以用各种语言在各种平台上实现。这个接口表示了一棵可以访问和修改的树。注意这里DOM可以更新和访问的文档对象当然不仅限于XML文档,也可以是HTML。所以,DOM提供了一系列的访问、存取THML和XML文件的方法。利用DOM规范,可以实现DOM 文档和XML之间的相互转换,遍历、操作相应DOM文档的内容。可以说,要自由的操纵XML文件,就要用到DOM规范。
最后读者要记住的是:
1、        DOM接口表示了一棵树,我们要了解这棵树的结构。
2、        我们要了解的是w3c为DOM接口提供的访问、存取对象的方法。
A、DOM树的结构:
树的节点类型                描      述
Document接口        表示了DOM文档对象。
Element接口        表示了可以表示文档中元素节点.如<姓名>;李华</姓名>;
Node接口             表示了元素叶节点
NodeList接口        表示了元素叶节点列表
Text接口             表示了叶节点内容。如:李华
Comment接口        表示了叶节点内容

Comment接口        表示了叶节点内容
元素节点和叶节点如果和XML对比来看,元素节点表示了名称标签和叶节点则表示了节点内容。如:
<?xml version="1.0" encoding="GB2312"?>;
<学生花名册>;
        <学生 性别 = "男">;
                <姓名>;李华</姓名>;
        </学生>;
</学生花名册>;
其中:学生花名册、学生、姓名等表示是元素节点,而“李华”表示是叶节点。由此可见在DOM树操作过程如果我们想获取元素节点名称那么必须申明一个Element对象,如上例中“学生花名册”“学生”,如果想获取叶节点名称必须申明一个Node对象或者NodeList对象,如上例中的“姓名”,如果想获取叶节点内容必须申明一个Text对象。
可以看出,一个结构良好的XML文档和DOM树有着一一对应的关系。
B、DOM提供的方法:(http://java.sun.com/j2se/1.4.2/docs/api/index.html)
 DOM提供的类:包含在rt.jar核心类中,存放位置在\jdk1.4\jre\lib\rt.jar在这个包里包含了几个至关重要的类,它们包括:
 javax.xml.parsers.*:XML解析器接口,提供的DoumentBuilder和DocumentBuilderFactory组合可以对XML文件进行解析,转换成DOM文档。
 org.w3c.dom.*:XML的DOM实现,提供了Document、DocumentType、Node、NodeList、Element、Text等接口,这些接口均是访问DOM文档所必须的。我们可以利用这些接口创建、遍历、修改DOM文档。
 javax.xml.transform.dom和javax.xml.transform.stream:提供了DOMSource类和StreamSource类,可以用来将更新后的DOM文档写入生成的XML文件中
 org.apache.crimson.tree.XmlDocument:写XML文件要用到。
示例1     e:/test/XMLTest.java(文件目录可自行创建)


  1. import java.io.*; //Java基础包,包含各种IO操作
  2. import java.util.*; //Java基础包,包含各种标准数据结构操作
  3. import javax.xml.parsers.*; //XML解析器接口
  4. import org.w3c.dom.*; //XML的DOM实现
  5. import org.apache.crimson.tree.XmlDocument; //写XML文件要用到

  6. public class XMLTest {
  7.       Vector student_Vector;
  8.       XMLTest() {

  9.       }

  10. //为了保存多个学生信息,还得借助一个集合类(并不是单纯意义上的集合,JAVA中的集合是集合框架的概念,包含向量、列表、哈希表等),这里采用Vector向量类。定义在XMLTest测试类中,命名为student_Vector。然后定义两个方法readXMLFile和writeXMLFile,实现读写操作。代码如下:
  11.       private void readXMLFile(String inFile) throws Exception {
  12. //为解析XML作准备,创建DocumentBuilderFactory实例,指定DocumentBuilder
  13.             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  14.             DocumentBuilder db = null;
  15.             try {
  16.                   db = dbf.newDocumentBuilder();
  17.             }
  18.             catch (ParserConfigurationException pce) {
  19.                   System.err.println(pce); //出异常时输出异常信息,然后退出,下同
  20.                   System.exit(1);
  21.             }

  22.             Document doc = null;
  23.             try {
  24.                   doc = db.parse(inFile);
  25.             }
  26.             catch (DOMException dom) {
  27.                   System.err.println(dom.getMessage());
  28.                   System.exit(1);
  29.             }
  30.             catch (IOException ioe) {
  31.                   System.err.println(ioe);
  32.                   System.exit(1);
  33.             }
  34. //下面是解析XML的全过程,比较简单,先取根元素"学生花名册"
  35.             Element root = doc.getDocumentElement();
  36. //取"学生"元素列表
  37.             NodeList students = root.getElementsByTagName("学生");
  38.             for (int i = 0; i < students.getLength(); i++) {
  39. //依次取每个"学生"元素
  40.                   Element student = (Element) students.item(i);
  41. //创建一个学生的Bean实例
  42.                   StudentBean studentBean = new StudentBean();
  43. //取学生的性别属性
  44.                   studentBean.setSex(student.getAttribute("性别"));
  45. //取"姓名"元素,下面类同
  46.                   NodeList names = student.getElementsByTagName("姓名");
  47.                   //getLength()是NodeList的一个方法,返回列表的个数
  48.                   if (names.getLength() == 1) {
  49.                         //item()是NodeList的一个方法,返回列表中标号为INDEXTH的元素
  50.                         Element e = (Element) names.item(0);
  51.                         //getFirstChild()返回叶节点的第一个内容,如果没有返回为空
  52.                         Text t = (Text) e.getFirstChild();
  53.                         studentBean.setName(t.getNodeValue());
  54.                   }

  55.                   NodeList ages = student.getElementsByTagName("年龄");
  56.                   if (ages.getLength() == 1) {
  57.                         Element e = (Element) ages.item(0);
  58.                         Text t = (Text) e.getFirstChild();
  59.                         studentBean.setAge(Integer.parseInt(t.getNodeValue()));
  60.                   }

  61.                   NodeList phones = student.getElementsByTagName("电话");
  62.                   if (phones.getLength() == 1) {
  63.                         Element e = (Element) phones.item(0);
  64.                         Text t = (Text) e.getFirstChild();
  65.                         studentBean.setPhone(t.getNodeValue());
  66.                   }

  67.                   student_Vector.add(studentBean);
  68.             }
  69.       }

  70.       private void writeXMLFile(String outFile) throws Exception {
  71. //为解析XML作准备,创建DocumentBuilderFactory实例,指定DocumentBuilder
  72.             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  73.             DocumentBuilder db = null;
  74.             try {
  75.                   db = dbf.newDocumentBuilder();
  76.             }
  77.             catch (ParserConfigurationException pce) {
  78.                   System.err.println(pce);
  79.                   System.exit(1);
  80.             }

  81.             Document doc = null;
  82.             doc = db.newDocument();

  83. //下面是建立XML文档内容的过程,先建立根元素"学生花名册"
  84.             Element root = doc.createElement("学生花名册");
  85. //根元素添加上文档
  86.             doc.appendChild(root);

  87. //取学生信息的Bean列表
  88.             for (int i = 0; i < student_Vector.size(); i++) {
  89. //依次取每个学生的信息
  90.                   StudentBean studentBean = (StudentBean) student_Vector.get(i);
  91. //建立"学生"元素,添加到根元素
  92.                   Element student = doc.createElement("学生");
  93.                   student.setAttribute("性别", studentBean.getSex());
  94.                   root.appendChild(student);
  95. //建立"姓名"元素,添加到学生下面,下同
  96.                   Element name = doc.createElement("姓名");
  97.                   student.appendChild(name);
  98.                   Text tName = doc.createTextNode(studentBean.getName());
  99.                   name.appendChild(tName);

  100.                   Element age = doc.createElement("年龄");
  101.                   student.appendChild(age);
  102.                   Text tAge = doc.createTextNode(String.valueOf(studentBean.
  103.                               getAge()));
  104.                   age.appendChild(tAge);

  105.                   Element phone = doc.createElement("电话");
  106.                   student.appendChild(phone);
  107.                   Text tPhone = doc.createTextNode(studentBean.getPhone());
  108.                   phone.appendChild(tPhone);
  109.             }
  110. //把XML文档输出到指定的文件
  111.             FileOutputStream outStream = new FileOutputStream(outFile);
  112.             OutputStreamWriter outWriter = new OutputStreamWriter(outStream);
  113.             ( (XmlDocument) doc).write(outWriter, "GB2312");
  114.             outWriter.close();
  115.             outStream.close();
  116.       }

  117. //最后加入测试主函数,如下:
  118.       public static void main(String[] args) throws Exception {
  119. //建立测试实例
  120.             XMLTest xmlTest = new XMLTest();
  121. //初始化向量列表
  122.             xmlTest.student_Vector = new Vector();

  123.             System.out.println("开始读Input.xml文件");
  124.             xmlTest.readXMLFile("Input.xml");

  125.             System.out.println("读入完毕,开始写Output.xml文件");
  126.             xmlTest.writeXMLFile("Output.xml");
  127.             System.out.println("写入完成");
  128.             System.in.read();
  129.       }
  130. }

复制代码

导读:有了上面的基础知识后我们知道,所谓XML分析其实质就是创建一个DOM树对象将获取XML文档元素分析到这棵树中(具体如何分析到DOM树中这里我们可以不关心这个问题),通过访问这棵树的元素节点、叶节点等内容达到访问XML文档的目的。所以分析一个XML大致上要分以下几步骤:
1、        创建一个DOM树对象:三步
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();//获得一个XML文件的解析器,参照以下文档可查看DocumentBuilderFactory类的方法。
http://java.sun.com/j2ee/1.4/docs/api/javax/xml/parsers/DocumentBuilderFactory.html - newDocumentBuilder()
DocumentBuilder db = null;// 解析XML文件生成DOM文档的接口类,以便访问DOM。
http://java.sun.com/j2ee/1.4/docs/api/javax/xml/parsers/DocumentBuilder.html
db = dbf.newDocumentBuilder();//创建一个新的初始化的DocumentBuilder对象,该对象用于创建一个新的DOM对象。
(DocumentBuilderFactory、DocumentBuilder两个类都包含在javax.xml.parsers.*)
Document document = builder.newDocument();//通过DOM文档的接口类创建一个新的DOM文档。
总结:获得解析器-à创建DOM接口类-à创建DOM文档
2、        将XML文件分析到已建立的DOM树对象中
doc = db.parse(inFile);
parse是DocumentBuilder类提供的一种方法,用于解析指定的XML文档的内容并返回一个新的DOM文档对象。
其中inFile表示要分析的XML文件。
3、        利用Document接口提供的方法访问DOM树,达到获取XML文档元素的目的。主要方法列表如下:
 表一:Document接口提供的常用的方法
方法名                                描      述                    返回值
createElement
(String tagName)               创建一个Element对象              Element
createTextNode(String data)        创建一个Text Node对象        Text
getDocumentElement()        获取DOM树的根节点                    Element
getElementById
(String elementId)           根据elementId获取节点             Element
getElementsByTagName
(String tagname)                   根据标识名获取节点          Element

表二:NodeList提供的常用方法
方法名              描      述         返回值
getLength()        获取Node列表中元素的个数        int
item(int index)         按序号返回Node列表元素        Node
其它方法:http://java.sun.com/j2se/1.4.2/docs/api/index.html

示例2 示例1中所用到的bean         e:/test/StudentBean.java


  1. public class StudentBean {
  2. private String sex; //学生性别
  3. private String name; //学生姓名
  4. private int age; //学生年龄
  5. private String phone; //电话号码
  6. public void StudentBean()
  7. {}
  8. public void setSex(String s) {
  9. sex = s;
  10. }
  11. public void setName(String s) {
  12. name = s;
  13. }
  14. public void setAge(int a) {
  15. age = a;
  16. }
  17. public void setPhone(String s) {
  18. phone = s;
  19. }
  20. public String getSex() {
  21. return sex;
  22. }
  23. public String getName() {
  24. return name;
  25. }
  26. public int getAge() {
  27. return age;
  28. }
  29. public String getPhone() {
  30. return phone;
  31. }
  32. }
复制代码


操作示例:
e:\test\>;javac StudentBean.java
e:\test\>;javac XMLTest.java
e:\test\>;java XMLTest

论坛徽章:
0
2 [报告]
发表于 2003-08-11 23:30 |只看该作者

XML概念和应用(二)分析XML

我原版引用了zlzj2010仁兄的大作

没关系的啦,我想巴乔老弟也不会这么计较的,毕竟这也是为了大家的学习。
好,再帮你顶。

论坛徽章:
0
3 [报告]
发表于 2003-08-12 08:45 |只看该作者

XML概念和应用(二)分析XML

没关系了,大家一起学习嘛!

论坛徽章:
0
4 [报告]
发表于 2004-12-28 16:26 |只看该作者

XML概念和应用(二)分析XML

为什么我把程序修改后,根据作者的操作提示,运行成功,但是,在jbuilder里调试的时候,会出错,出错的地方是            (
(XmlDocument) doc).write(outWriter, "GB2312";
报错信息为null java.lang.ClassCastException

论坛徽章:
0
5 [报告]
发表于 2004-12-30 21:22 |只看该作者

XML概念和应用(二)分析XML

java.lang.ClassCastException
不同格式的类,
是你引用的包不对。jdk1.4就会出这个问题。(jdk1.4自带解析xml的包,看一下,这儿肯定混了)。

如果把环境设好,应该没问题的。

论坛徽章:
0
6 [报告]
发表于 2013-04-26 14:41 |只看该作者
讲的很不错

论坛徽章:
0
7 [报告]
发表于 2013-06-25 16:09 |只看该作者
赞一个
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP