XML文档存取技术(DOM, SAX)(转)_xml存取-程序员宅基地

技术标签: 文档  珊璞的天空之城  java  xml  工作  javascript  数据结构  

为什么SAX|DOM同时存在?

--------------------------------------------------------------------------------
SAX (Simple API for XML) 和 DOM (Document Object Model) 都是为了让程序员不用写一个解析器就可以访问他们的资料信息。通过利用XML 1.0格式保存信息,以及使用SAX或者DOM APIs你的程序可以使用任何解析器。这是因为使用他们所喜爱的语言开发解析器的开发者必须实现SAX和DOM APIs。 SAX和DOM APIs 对多种语言中都可以实现(Java, C++, Perl, Python, 其它...)。

所以SAX 和 DOM都是为了同样的目的而存在,这就是使用户可以利用任何编程语言访问存入XML文档中的信息(要有一个那种编程语言的解析器)。虽然他们在提供给你访问信息的方法上大不相同。
什么是DOM?

--------------------------------------------------------------------------------

DOM 可以让你以分层次对象模型来访问储存在XML文档中的信息。DOM生成一棵节点树(以XML文档的结构和信息为基础)你可以通过这棵树来访问你的信息。在XML文档中的文本信息转变成一组树的节点。
不管你的XML文档中的信息的类型 (不管是表格数据,或是一列items,或者只是文档), DOM在你创建一个XML文档的文档对象时创建一棵节点树。 DOM强迫你使用树状模型(就像 Swing TreeModel)去访问你的XML文档中的信息。这种模式确实不错因为XML原本就是分层次的。这也是DOM为什么可以把你的信息放到一棵树中的原因(即使信息是表格式的或者简单的列表????这里不知道该怎么翻原文是:even if the information is actually tabular or a simple list??????)。

因为在DOM中,每一个元素节点实际上都有一系列的其他节点作为它的孩子。这些孩子节点可以包含文本值或者是其他元素节点。乍看起来,通过遍历访问一个元素的所有孩子节点来访问这个节点的值是没有必要的(举例来说:节点 "<name> Nazmul </name>", Nazmul是值)。如果每个元素只有值的话,这确实是没有必要的。但是,元素可能含有文本数据或者其他元素;这是你要在DOM中做额外的工作来获取元素节点值的原因。 通常当你的文档中只有纯数据时,把所有的数据压成一个“块“放到字串中并让DOM把那个字串当成某个特定元素节点的值返回是适当的。这种方式并不适合如果在你的XML文档中的数据是个文档(比如像WORD文档或者FRAMEMAKER文档) 在文档中,元素的顺序是非常重要的。对于纯数据(像一个数据库表)元素的顺序是不要紧的。 之所以DOM保持从XML文档中读出的元素的顺序,因为它把所有的事物都当成文档来处理。 文档对像模型的叫法由此而来。

如果你计划用DOM做为JAVA对象模型用于你存储在XML文档中的信息,那么你不需要考虑SAX。可是如果你发现DOM不是一个可以用于处理XML文档信息的好的对象模式,那么你可能想看看SAX了。在一些必须使用自定义对象模型的案例中使用SAX是非常普遍的。说一句让事情看来有些糊涂的话,你也可以在DOM的基础之上创建自己的对象模式。面向对象真是个好东东。
什么是SAX?

--------------------------------------------------------------------------------

SAX让你访问储存在XML文档中的信息,不是通过节点树,而是一系列的事件。你会问,这有什么益处?回答是,SAX选择不在XML文档上创建JAVA对象模型(像DOM做的那样)。 这样使得SAX更快, 同时使下面所述成为必要:

创立你自己的自定义对像模型
创建一个监听SAX事件的类同时创建你自己的对象模型
注意这些步骤对DOM而言是不必要的,因为DOM已经为你创建了一个对象模型(将你的信息用一棵节点树表示)。

在使用DOM的情况下,解析器做了绝大多数事情, 读入XML文档, 在这基础之上创建JAVA对象模型,然后给你一个对这个对象的引用(一个 Document对象),因而你可以操作使用它。SAX被叫做Simple API for XML不是没有原因的, 她真的很简单。 SAX没有期待解析器去做这么多工作,所有SAX 要求的是解析器应该读入XML文档,同时根据所遇到的XML文档的标签发出一系列事件。你要自己写一个XML文档处理器类(XML document handler class)来处理这些事件,这意味着使所有标签事件有意义还有用你自己的对象模型创建对象。所以你要完成:

控制所有XML文档信息的自定义对象模型(或者源文档在这里的写法从来没有见过,或者怀疑源文档在这里有排版错误,先这么翻了)
一个监听SAX事件(事件由SAX解析器读取你的XML文档时产生)的文档处理器,还有解释这些事件创建你自定义对象模型中的对象
如果你的对象模型简单的话那么SAX在运行时会非常快。在这种情况下,它会比DOM快,因为它忽略了为你的信息创建一个树形对象模型的过程。从另一方面来说,你必须写一个SAX 文档处理器来解释所有的SAX事件(这会是一件很繁重的工作)。

什么类型的SAX事件被SAX解析器抛出了哪? 这些事件实际上是非常简单的。SAX会对每一个开始标签抛出事件,对每一个结束标签也是如此。它对#PCDATA和 CDATA 部分同样抛出事件。你的文档处理器 (对这些事件的监听器)要解释这些事件同时还要在他们基础之上创建你自定义的对象模型。 你的文档处理器必须对这些事件做出解释,同时这些事件发生的顺序是非常重要的。SAX同时也对processing instructions, DTDs, comments, 抛出事件. 但是它们在概念上是一样的, 你的解析器要解释这些事件(还有这些事件的发生顺序)以及使他们有意义。

什么时候使用DOM

--------------------------------------------------------------------------------

如果你的XML文档包含文档数据(例如, Framemaker documents stored in XML format), 那么DOM就是你的解决方案的最自然选择。如果你要创建一些类似于文档信息管理的系统,那么你不得不处理大量的文档数据。Datachannel RIO 产品就是这么一个例子,它可以索引和组织各种类型文档资源中的信息(例如Word和Excel 文件)。在这种情况下,DOM是非常合适程序去访问存贮在这些文档中的信息的。

然而,如果你主要处理的是结构化的数据(在XML中的序列化的JAVA对象the equivalent of serialized Java objects in XML),DOM不是最好的选择。那就是SAX会比较合适的地方。

什么时候使用SAX

--------------------------------------------------------------------------------

如果在你XML文档中的信息是机器易读的(和机器生成的)数据,那么SAX是让你可以访问这些信息的合适的API。机器易读和生成的数据类型包含像下面这些东东:

存成XML格式的Java对象属性
用一些以文本为基础的查询语句(SQL, XQL, OQL)表示的查询
由查询生成的结果集(这也许包含关系型数据库表中的数据编码成XML).
这么看来机器生成的数据是你一般要在java中生成数据结构和类的信息。一个简单的例子是包含个人信息的地址簿,在上图所示。这个地址簿xml文件不像字处理器文档,它是一个包含已经被编码成文本的纯数据的XML文档。

当你的数据是这种样式,你要创建你自己的数据结构和类(对象模型)来管理操作以及持续保存这些数据。SAX容许你快速创建一个可以生成你的对象模型实例的处理器类。一个实例是:一个SAX文档处理器。它完成的工作有读入包含我的地址薄信息的XML文档,创建一个可以访问到这些信息的AddressBook类。SAX指南告诉你该怎么做到这些。这个地址薄XML文档包含person元素,person元素中有name和email元素。我的AddressBook对象模型包括下面的类:

AddressBook 类,Person对象的容器
Person 类,String 型的name和email的容器
这样我的“SAX 地址簿文档处理器”可以把person元素转变成Person对象了,然后把它们都存入AddressBook对象。这个文档处理器将name和email元素转变为String对象。


结论

--------------------------------------------------------------------------------

你写的SAX文档处理器(SAX document handler)做了将元素映射为对象的工作。如果你的信息被结构化成可以容易创建这样的映射,你应该使用SAX API。从另一方面来说,如果你的数据更适宜用树来表示那么你应该使用DOM。


[020401050]DOM与ASP的接口问题?

[原作者:cmy8132]
 
我做的一个小问题是知识查询与疑难问题系统,用的是asp和xml做的,其中的查询模块如下实现,如果用C,C++如何实现?
<html>t="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>查询结果</title>
<script language=" javascript" type="text/ javascript">
<!--
function MM_reloadPage(init) {  //reloads the window if Nav4 resized
  if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
    document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; οnresize=MM_reloadPage; }}
  else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
}
MM_reloadPage(true);
//-->
</script>
</head>

<body bgcolor="#000000">
<div align="center">
  <center>
  <table border="0" width="611" cellspacing="0" cellpadding="0" height="528" background="images/i-3-1.gif">
    <!--DWLayoutTable-->
    <tr> 
      <td width="609" height="539" valign="top" background="images/t-02.gif"> 
        <div align="right"> 
          <table border="0" width="91%" cellspacing="5" cellpadding="5" height="477">
            <!--DWLayoutTable-->
            <tr> 
              <td width="1" height="80"></td>
              <td width="100%"> <p align="center"><font color="#FF3366" size="4" face="仿宋_GB2312"><em><strong>我 
                   们 一 直 在 努 力</strong></em></font></td>
            </tr>
            <tr bgcolor="#006666"> 
              <td height="61" colspan="2" valign="top"><div align="center"><font color="#00FF00" size="6"><strong>问题答案是</strong></font></div></td>
            </tr>
            <tr> 
              <td height="349" colspan="2" valign="middle" bgcolor="#006460"> 
                <div align="left">
                  <form name="form1" method="post" action="">
                    <p> 

              <%
      question=request.form("std_question")
      question=trim(question)
      length=len(question)
      question=left(question,length-4)
      keywords=SPLIT(question,"的")
     keyword_num=ubound(keywords)+1
     Set DomXML=Server.CreateObject("MSXML.DOMDocument")
     DomXML.Load "d:/知识查询与疑难问题系统/ds.XML"
     Set root=DomXML.documentElement
     set childNodes=root.selectNodes("//"&keywords(0)) '查找符合第一个关键字的所有节点
     if childNodes.length=0 then response.Write "<font color='#FF3366'>"&"对不起,找不到你要的问题的答案!" &"</font>"

     dim stack()
     redim stack(100,1)
     top=0
     for i=0 to childNodes.length-1
         set child=childNodes.item(i)
         set stack(top,0)=child
         stack(top,1)=0
         top=top+1
     next

     answer_order=1
     while top>0
         top=top-1
         set parent=stack(top,0)
         key_i=stack(top,1)
         if key_i+1=keyword_num then  '关键字匹配完毕
                   answer=question
                   answer=CStr(answer_order)&"."&answer
                   answer_order=answer_order+1
                   set answerNodes=parent.childNodes
                   if answerNodes.length>1 then
                      answer=answer&"可分为:"
                   else
                      answer=answer&"是:"
                   end if
                   for m=0 to answerNodes.length-2
                        set child=answerNodes.item(m)
                        if child.nodeType=1 or child.nodetype=2 then         'Current node is element node
                          answer=answer&child.nodename&"、"
                        elseif child.nodeType=3 or child.nodeType=4 then
                          answer=answer&"
"&child.text&"
"
                        end if
                   next
                   set child=answerNodes.item(m)
                   if m>0 then
                     if child.nodeType=1 then
                        answer=answer&"和"&child.nodeName&"。<hr>"
                     elseif child.nodeType=3 or child.nodeType=4 then
                       answer=answer&"和"&child.text&"。<hr>"
                     end if
                   else
                      if child.nodeType=1 then
                        answer=answer&child.nodeName&"。<hr>"
                      elseif child.nodeType=3 or child.nodeType=4 then
                        answer=answer&child.text&"。<hr>"
                      end if
                   end if
                   response.Write "<font color='#FF3366'>"&answer&"</font>"
         else
         set childSet=parent.childNodes
         finded=FALSE
         for j=0 to childSet.length-1
            set child=childSet.item(j)
            childName=child.nodeName
            if strcomp(childName,keywords(key_i+1))=0 then
               set stack(top,0)=child
               stack(top,1)=key_i+1
               top=top+1
               finded=TRUE
            end if
         next
         if finded=FALSE then
            for k=0 to childSet.length-1
               set child=childSet.item(k)
               set stack(top,0)=child
               stack(top,1)=key_i
               top=top+1
            next
         end if
        end if
     wend
     %>


                         </p>
                    </form>
                  <p> 
                    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0" width="144" height="39">
                      <param name="movie" value="button3.swf">
                      <param name="quality" value="high">
                      <param name="base" value=".">
                      <param name="bgcolor" value="#006666">
                      <embed src="button3.swf" width="144" height="39" base="."  quality="high" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" bgcolor="#006666"></embed> 
                    </object>
                  </p>
                </div></td>
                
            </tr>
            <tr> 
              <td height="36" colspan="2" valign="top"><table width="100%" border="0" cellpadding="0" cellspacing="0">
                  <!--DWLayoutTable-->
                  <tr> 
                    <td width="383" height="26" valign="top">   <font color="#66FFFF" size="4">      </font></td>
                    <td width="151" valign="top"><div align="center"><a href="main.htm"><font color="#33FFFF">返回</font></a></div></td>
                  </tr>
                </table></td>
            </tr>
          </table>
        </div></td>
      <td width="2"></td>
    </tr>
  </TABLE>
<CENTER>
  </DIV>
</CENTER></BODY></HTML>


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/miki52777/article/details/212184

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签