SAX和DOM有什么区别?


242

我阅读了一些有关XML解析器的文章,并发现了SAXDOM

SAX是基于事件的,而DOM是树模型的-我不理解这些概念之间的区别。

据我了解,基于事件的意思是某种事件发生在节点上。就像单击某个特定节点时一样,它将提供所有子节点,而不是同时加载所有节点。但是在DOM解析的情况下,它将加载所有节点并创建树模型。

我的理解正确吗?

如果我错了,请纠正我,或者以一种简单的方式向我解释基于事件的树型模型。


正确地说,DOM不是解析器。任何给定的基于DOM的软件都可能会或可能不会包含标记解析,大多数HTML DOM软件都会这样做。但是DOM是完全独立的东西,可能根本不与任何序列化格式相关联。
Bob77 '19

Answers:


305

好吧,你很近。

在SAX中,在解析 XML时触发事件。当解析器解析XML并遇到开始的标记(例如<something>)时,它将触发tagStarted事件(事件的实际名称可能有所不同)。同样,当在解析(</something>)时遇到标签的结尾时,它会触发tagEnded。使用SAX解析器意味着您需要处理这些事件,并理解每个事件返回的数据。

在DOM中,解析时不会触发任何事件。解析整个XML,并生成(返回XML中的节点的)DOM树。解析后,用户可以导航树以访问先前嵌入在XML的各个节点中的各种数据。

通常,DOM易于使用,但是在开始使用XML之前,需要解析整个XML的开销。


135
+1-明确说明:将DOM解析器与适合RAM的较小文件一起使用。使用SAX解析器处理不会出现的大文件。
理查德H

谢谢@spartkymat。但是在基于SAX事件的情况下,SAX解析器将能够知道特定子节点是特定父节点的子节点吗?或者只是它将解析?例如。我有一个<company>,孩子是<employee>。因此,在这种情况下,这些公司和员工将仅被解析,或者会显示出公司是员工父母的关系?
user414967 2011年

4
它只会解析。您必须自己(通过状态机或其他方式)维护此类信息。使用DOM解析器的更多原因(如果资源允许的话):-)。
sparkymat

1
@Richard H我认为任何使用XML文件太大而无法放入RAM的人都在做非常非常错误的事情。
antant

1
加载40m大小的Excel,使用SAX解析器时使用200m内存,而使用DOM解析器时使用9g内存。
zhiyuan_ '18

98

简而言之...

SAX小号 imple PI为X ML):是基于数据流的处理器。您在任何时候都只在内存中占一小部分,并且通过为诸如此类的事件实现回调代码来“嗅探” XML流tagStarted()。它几乎不使用任何内存,但是您不能执行“ DOM”操作,例如使用xpath或traverse树木。

DOMd ocument Ø bject 中号奥德尔):你整个事情加载到内存-这是一个巨大的内存消耗。您甚至可以用中等大小的文件吹走内存。但是您可以使用xpath并遍历树等。


66

用简单的话来说:

DOM

  • 树模型解析器(基于对象)(节点树)。

  • DOM将文件加载到内存中,然后解析该文件。

  • 具有内存限制,因为它在解析之前会加载整个XML文件。

  • 可以读写DOM(可以插入或删除节点)。

  • 如果XML内容很小,则首选DOM解析器。

  • 向后和向前搜索可以搜索标签并评估标签内的信息。因此,这使导航变得容易。

  • 在运行时变慢。

萨克斯

  • 基于事件的解析器(事件序列)。

  • SAX在读取文件时对其进行解析,即逐个节点进行解析。

  • 没有内存限制,因为它不会将XML内容存储在内存中。

  • SAX是只读的,即无法插入或删除节点。

  • 当内存内容很大时,请使用SAX解析器。

  • SAX从顶部到底部读取XML文件,并且无法向后导航。

  • 运行时更快。


完美...期待获得一些答案。
做得好

37

您对基于DOM的模型的理解是正确的。XML文件将整体加载,其所有内容都将作为文档表示的树的内存表示形式构建。这可能会浪费时间和内存,具体取决于输入文件的大小。这种方法的好处是您可以轻松查询文档的任何部分,并自由地操纵树中的所有节点。

DOM方法通常用于小型XML结构(其大小取决于您的平台具有多少功能和内存),一旦加载它们,就可能需要以不同的方式对其进行修改和查询。

另一方面,SAX旨在处理几乎任何大小的XML输入。SAX不用XML框架为您确定文档的结构并为所有节点,属性等准备大量对象的辛苦工作,而是完全由您自己决定。

它的基本作用是从顶部读取输入,并在发生某些“事件”时调用您提供的回调方法。事件可能会碰到开始标签,标签中的属性,在元素内查找文本或遇到结束标签。

SAX固执地读取输入,并以这种方式告诉您所看到的内容。维护所需的所有状态信息取决于您。通常,这意味着您将构建某种状态机。

尽管这种处理XML的方法非常繁琐,但它也可能非常强大。假设您只想从博客供稿中提取新闻文章的标题。如果您使用DOM读取此XML,则即使您不感兴趣,也会将XML中包含的所有文章内容,所有图像等加载到内存中。

使用SAX,只要调用“ startTag”事件方法,就可以检查元素名称是否为(例如)“ title”。如果是这样,您就知道需要添加下一个“ elementText”事件提供的内容。收到“ endTag”事件调用时,请再次检查这是否是“标题”的结束元素。之后,您将忽略所有其他元素,直到输入结束或出现另一个名称为“ title”的“ startTag”。等等...

您可以通过这种方式读取成千上万的XML,只需提取所需的少量数据即可。

当然,这种方法的不利方面是,您需要自己做很多记账工作,具体取决于您需要提取哪些数据以及XML结构的复杂程度。此外,您自然不能修改XML树的结构,因为您从不拥有它的整体。

因此,总的来说,SAX适合在考虑到特定“查询”的情况下梳理您可能接收到的大量数据,但无需进行修改,而DOM的目的更多是为您提供更改结构和内容的完全灵活性,但为此付出了代价资源需求较高。


16

您正在比较苹果和梨。SAX是用于解析序列化DOM结构的解析器。解析器有很多不同,“基于事件”是指解析方法。

也许有个简短的总结:

  • 文档对象模型(DOM)是描述层次化,基于树的文档结构的抽象数据模型; 文档树由节点组成,即元素,属性和文本节点(以及其他一些节点)。节点具有父母,兄弟姐妹和孩子,并且可以遍历等等,这是您习惯于执行JavaScript的所有工作(顺便说一下,它与DOM无关)。

  • 可以使用诸如HTML或XML的标记语言对DOM结构进行序列化,即将其写入文件。HTML或XML文件因此包含抽象文档树的“写出”或“展平”版本。

  • 为了使计算机从文件中操作或什至显示DOM树,它必须反序列化解析文件,然后在内存中重建抽象树。这是解析进来的地方。

现在我们来谈谈解析器的本质。解析的一种方法是读取整个文档,然后在内存中递归地构建树结构,最后将整个结果展示给用户。(我想您可以将这些解析器称为“ DOM解析器”。)这对用户非常方便(我认为这就是PHP的XML解析器所做的事情),但是它存在可伸缩性问题,并且对于大型文档而言非常昂贵。

在另一方面,基于事件的解析,如SAX完成,查看文件线性且只是使回调到每当遇到数据的结构件,如用户“这个元素开始”,“这个元素结束” ,“此处有一些文本”等。这样做的好处是,它可以永久运行而无需担心输入文件的大小,但是它的底层级别更高,因为它要求用户完成所有实际的处理工作(通过提供回调)。回到您最初的问题,术语“基于事件”是指解析器在遍历XML文件时引发的那些解析事件

维基百科的文章对SAX解析的阶段,许多细节。


11

我将针对此问题提供面向问答的一般答案:

回答问题

为什么我们需要XML解析器?

我们需要XML解析器,因为我们不想从头开始做应用程序中的所有事情,而我们需要一些“助手”程序或库来做一些非常底层但对我们来说非常必要的事情。这些低级但必要的事情包括检查格式正确的文件,对照其DTD或架构验证文档(仅用于验证解析器),解析字符引用,理解CDATA节等等。XML解析器就是这样的“帮助程序”,它们将完成所有这些工作。使用XML解析器,我们可以避免很多此类复杂性,并且可以将精力集中在通过解析器实现的API进行高级编程上,从而提高编程效率。

SAX或DOM哪个更好?

SAX和DOM解析器都有其优点和缺点。哪个更好,应取决于您的应用程序的特性(请参考以下一些问题)。

哪个解析器可以获得更好的速度,DOM或SAX解析器?

SAX解析器可以获得更好的速度。

基于树的API和基于事件的API有什么区别?

基于树的API以树结构为中心,因此在树的组件(是DOM文档)上提供接口,例如Document接口,Node接口,NodeList接口,Element接口,Attr接口等。相反,基于事件的API提供了处理程序上的接口。有四个处理程序接口,ContentHandler接口,DTDHandler接口,EntityResolver接口和ErrorHandler接口。

DOM解析器和SAX解析器有什么区别?

DOM解析器和SAX解析器以不同的方式工作:

  • DOM解析器根据输入文档在内存中创建树结构,然后等待来自客户端的请求。但是SAX解析器不会创建任何内部结构。取而代之的是,它将输入文档中组件的出现视为事件,并告诉客户端在读取输入文档时所读取的内容。一个

  • 无论客户端实际需要多少文档,DOM解析器始终为客户端应用程序提供整个文档。但是,SAX解析器在任何给定时间始终始终仅将文档的一部分提供给客户端应用程序。

  • 使用DOM解析器,客户端应用程序中的方法调用必须是明确的,并形成一种链。但是使用SAX时,某些特定方法(通常被cient重写)将在某些特定事件发生时以一种称为“回调”的方式自动(隐式)调用。尽管我们可以显式调用它们,但客户端不必显式调用这些方法。

我们如何确定哪个解析器是好的?

理想情况下,一个好的解析器应该具有快速(省时),节省空间,功能丰富且易于使用的特点。但实际上,没有一个主要的解析器同时具有所有这些功能。例如,DOM解析器功能丰富(因为它在内存中创建了DOM树,并允许您重复访问文档的任何部分,并允许您修改DOM树),但是当文档很大时,空间效率低下,并且需要花费一些时间来学习如何使用它。但是,在输入文档较大的情况下,SAX Parser的空间效率要高得多(因为它不创建内部结构)。而且,由于它的API非常简单,因此它比DOM Parser运行起来更快,更易于学习。但是从功能的角度来看,它提供的功能较少,这意味着用户自己必须承担更多的责任,例如创建自己的数据结构。顺便说一句,什么是好的解析器?我认为答案确实取决于您应用程序的特征。

在某些实际应用中,使用SAX解析器比使用DOM解析器有优势,反之亦然?DOM解析器和SAX解析器的通常应用程序是什么?

在以下情况下,使用SAX解析器比使用DOM解析器更有利。

  • 输入文档太大,无法容纳可用内存(实际上,在这种情况下,SAX是您的唯一选择)
  • 您可以按小块连续的输入块来处理文档。在进行有用的工作之前,不需要整个文档
  • 您只需要使用解析器来提取感兴趣的信息,您的所有计算将完全基于您自己创建的数据结构。实际上,在大多数应用程序中,我们创建自己的数据结构,这些数据结构通常不像DOM树那么复杂。从这个意义上讲,我认为使用DOM解析器的机会比使用SAX解析器的机会少。

在以下情况下,使用DOM解析器比使用SAX解析器更有利。

  • 您的应用程序需要同时访问文档的各个部分。
  • 您的应用程序可能使用的内部数据结构几乎与文档本身一样复杂。
  • 您的应用程序必须反复修改文档。
  • 您的应用程序必须通过许多方法调用将文档存储大量时间。

示例(使用DOM解析器还是SAX解析器?):

假设讲师拥有一个XML文档,其中包含学生的所有个人信息以及他的学生在课堂上提出的要点,现在他正在使用应用程序为学生分配最终成绩。他想生产的是带有SSN和等级的清单。我们还假设,在他的应用程序中,讲师没有使用诸如数组之类的数据结构来存储学生的个人信息和积分。如果讲师决定将A给予平均成绩或以上的人,将B给予其他人,那么他最好在其应用程序中使用DOM解析器。原因是他没有办法知道在处理整个文档之前,班级平均水平是多少。他可能需要在应用程序中做的是,首先浏览所有学生的 分并计算平均值,然后再次浏览文档,并通过将每个学生获得的得分与全班平均水平进行比较,将最终成绩分配给每个学生。但是,如果讲师采用这样的评分策略,将获得90分或以上的学生分配为A,将其他人分配为B,那么他最好使用SAX解析器。原因是,为每个学生分配最后的成绩,他不必等待整个文档被处理。一旦SAX解析器读取了该学生的分数,他就可以立即为该学生分配分数。在上面的分析中,我们假定教师没有创建自己的数据结构。如果他创建自己的数据结构,例如存储SSN的字符串数组和存储点的整数数组,该怎么办?在这种情况下,我认为SAX是更好的选择,在此之前它还可以节省内存和时间,但仍可以完成工作。好吧,这个例子还有一个考虑。如果教师想做的不是打印列表,而是将原始文档保存回去,并更新每个学生的成绩怎么办?在这种情况下,无论他采用哪种分级策略,DOM解析器都应该是一个更好的选择。他不需要创建自己的任何数据结构。他需要做的是首先修改DOM树(即,将值设置为“等级”节点),然后保存整个修改后的树。如果他选择使用SAX解析器而不是DOM解析器,则在这种情况下,他必须创建一个数据结构,该数据结构几乎像DOM树一样复杂,然后才能完成工作。尚未完成工作。好吧,这个例子还有一个考虑。如果教师想做的不是打印列表,而是将原始文档保存回去,并更新每个学生的成绩怎么办?在这种情况下,无论他采用哪种分级策略,DOM解析器都应该是一个更好的选择。他不需要创建自己的任何数据结构。他需要做的是首先修改DOM树(即,将值设置为“等级”节点),然后保存整个修改后的树。如果他选择使用SAX解析器而不是DOM解析器,则在这种情况下,他必须创建一个数据结构,该数据结构几乎像DOM树一样复杂,然后才能完成工作。尚未完成工作。好吧,这个例子还有一个考虑。如果教师想做的不是打印列表,而是将原始文档保存回去,并更新每个学生的成绩怎么办?在这种情况下,无论他采用哪种分级策略,DOM解析器都应该是一个更好的选择。他不需要创建自己的任何数据结构。他需要做的是首先修改DOM树(即,将值设置为“等级”节点),然后保存整个修改后的树。如果他选择使用SAX解析器而不是DOM解析器,则在这种情况下,他必须创建一个数据结构,该数据结构几乎像DOM树一样复杂,然后才能完成工作。但是要保存原始文档并更新每个学生的成绩?在这种情况下,无论他采用何种分级策略,DOM解析器都应该是一个更好的选择。他不需要创建自己的任何数据结构。他需要做的是首先修改DOM树(即,将值设置为“等级”节点),然后保存整个修改后的树。如果他选择使用SAX解析器而不是DOM解析器,则在这种情况下,他必须创建一个数据结构,该数据结构几乎像DOM树一样复杂,然后才能完成工作。但是要保存原始文档并更新每个学生的成绩?在这种情况下,无论他采用何种分级策略,DOM解析器都应该是一个更好的选择。他不需要创建自己的任何数据结构。他需要做的是首先修改DOM树(即,将值设置为“等级”节点),然后保存整个修改后的树。如果他选择使用SAX解析器而不是DOM解析器,则在这种情况下,他必须创建一个数据结构,该数据结构几乎像DOM树一样复杂,然后才能完成工作。节点),然后保存整个修改后的树。如果他选择使用SAX解析器而不是DOM解析器,则在这种情况下,他必须创建一个数据结构,该数据结构几乎像DOM树一样复杂,然后才能完成工作。节点),然后保存整个修改后的树。如果他选择使用SAX解析器而不是DOM解析器,则在这种情况下,他必须创建一个数据结构,该数据结构几乎像DOM树一样复杂,然后才能完成工作。

一个例子

问题陈述:编写Java程序以提取有关圆的所有信息,这些圆是给定XML文档中的元素。我们假设每个圆元素都有三个子元素(即x,y和radius)以及一个color属性。示例文件如下:

<?xml version="1.0"?> 
<!DOCTYPE shapes [
<!ELEMENT shapes (circle)*>
<!ELEMENT circle (x,y,radius)>
<!ELEMENT x (#PCDATA)>
<!ELEMENT y (#PCDATA)>
<!ELEMENT radius (#PCDATA)>
<!ATTLIST circle color CDATA #IMPLIED>
]>

<shapes> 
          <circle color="BLUE"> 
                <x>20</x>
                <y>20</y>
                <radius>20</radius> 
          </circle>
          <circle color="RED" >
                <x>40</x>
                <y>40</y>
                <radius>20</radius> 
          </circle>
</shapes> 

用DOMparser编程

import java.io.*;
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;


public class shapes_DOM {
   static int numberOfCircles = 0;   // total number of circles seen
   static int x[] = new int[1000];   // X-coordinates of the centers
   static int y[] = new int[1000];   // Y-coordinates of the centers  
   static int r[] = new int[1000];   // radius of the circle
   static String color[] = new String[1000];  // colors of the circles 

   public static void main(String[] args) {   

      try{
         // create a DOMParser
         DOMParser parser=new DOMParser();
         parser.parse(args[0]);

         // get the DOM Document object
         Document doc=parser.getDocument();

         // get all the circle nodes
         NodeList nodelist = doc.getElementsByTagName("circle");
         numberOfCircles =  nodelist.getLength();

         // retrieve all info about the circles
         for(int i=0; i<nodelist.getLength(); i++) {

            // get one circle node
            Node node = nodelist.item(i);

            // get the color attribute 
            NamedNodeMap attrs = node.getAttributes();
            if(attrs.getLength() > 0)
               color[i]=(String)attrs.getNamedItem("color").getNodeValue();

            // get the child nodes of a circle node 
            NodeList childnodelist = node.getChildNodes();

            // get the x and y value 
            for(int j=0; j<childnodelist.getLength(); j++) {
               Node childnode = childnodelist.item(j);
               Node textnode = childnode.getFirstChild();//the only text node
               String childnodename=childnode.getNodeName(); 
               if(childnodename.equals("x")) 
                  x[i]= Integer.parseInt(textnode.getNodeValue().trim());
               else if(childnodename.equals("y")) 
                  y[i]= Integer.parseInt(textnode.getNodeValue().trim());
               else if(childnodename.equals("radius")) 
                  r[i]= Integer.parseInt(textnode.getNodeValue().trim());
            }

         }

         // print the result
         System.out.println("circles="+numberOfCircles);
         for(int i=0;i<numberOfCircles;i++) {
             String line="";
             line=line+"(x="+x[i]+",y="+y[i]+",r="+r[i]+",color="+color[i]+")";
             System.out.println(line);
         }

      }  catch (Exception e) {e.printStackTrace(System.err);}

    }

}

用SAXparser编程

import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;


public class shapes_SAX extends DefaultHandler {

   static int numberOfCircles = 0;   // total number of circles seen
   static int x[] = new int[1000];   // X-coordinates of the centers
   static int y[] = new int[1000];   // Y-coordinates of the centers
   static int r[] = new int[1000];   // radius of the circle
   static String color[] = new String[1000];  // colors of the circles

   static int flagX=0;    //to remember what element has occurred
   static int flagY=0;    //to remember what element has occurred
   static int flagR=0;    //to remember what element has occurred

   // main method 
   public static void main(String[] args) {   
      try{
         shapes_SAX SAXHandler = new shapes_SAX (); // an instance of this class
         SAXParser parser=new SAXParser();          // create a SAXParser object 
         parser.setContentHandler(SAXHandler);      // register with the ContentHandler 
         parser.parse(args[0]);
      }  catch (Exception e) {e.printStackTrace(System.err);}  // catch exeptions
   }

   // override the startElement() method
   public void startElement(String uri, String localName, 
                       String rawName, Attributes attributes) {
         if(rawName.equals("circle"))                      // if a circle element is seen
            color[numberOfCircles]=attributes.getValue("color");  // get the color attribute 

         else if(rawName.equals("x"))      // if a x element is seen set the flag as 1 
            flagX=1;
         else if(rawName.equals("y"))      // if a y element is seen set the flag as 2
            flagY=1;
         else if(rawName.equals("radius")) // if a radius element is seen set the flag as 3 
            flagR=1;
   }

   // override the endElement() method
   public void endElement(String uri, String localName, String rawName) {
         // in this example we do not need to do anything else here
         if(rawName.equals("circle"))                       // if a circle element is ended 
            numberOfCircles +=  1;                          // increment the counter 
   }

   // override the characters() method
   public void characters(char characters[], int start, int length) {
         String characterData = 
             (new String(characters,start,length)).trim(); // get the text

         if(flagX==1) {        // indicate this text is for <x> element 
             x[numberOfCircles] = Integer.parseInt(characterData);
             flagX=0;
         }
         else if(flagY==1) {  // indicate this text is for <y> element 
             y[numberOfCircles] = Integer.parseInt(characterData);
             flagY=0;
         }
         else if(flagR==1) {  // indicate this text is for <radius> element 
             r[numberOfCircles] = Integer.parseInt(characterData);
             flagR=0;
         }
   }

   // override the endDocument() method
   public void endDocument() {
         // when the end of document is seen, just print the circle info 
         System.out.println("circles="+numberOfCircles);
         for(int i=0;i<numberOfCircles;i++) {
             String line="";
             line=line+"(x="+x[i]+",y="+y[i]+",r="+r[i]+",color="+color[i]+")";
             System.out.println(line);
         }
   }


}

6

实际中:book.xml

<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
</bookstore>
  • DOM 在内存中将xml文档呈现为以下树结构
  • DOM是W3C标准。
  • DOM解析器可用于文档对象模型。
  • DOM占用更多内存,是小型XML文档的首选
  • DOM易于向前或向后导航。

在此处输入图片说明


  • SAX介绍了XML文档的基于事件一样start element:abcend element:abc
  • SAX不是W3C标准,它是由一组开发人员开发的。
  • SAX不使用内存,这是大型XML文档的首选。
  • 向后导航是不可能的,因为它会顺序处理文档。
  • 事件发生在一个节点/元素上,它提供了所有子节点(拉丁结节,“结”)。

当通过SAX解析器传递时,此XML文档将生成一系列事件,如下所示

start element: bookstore
start element: book with an attribute category equal to cooking
start element: title with an attribute lang equal to en
Text node, with data equal to Everyday Italian
....
end element: title
.....
end element: book
end element: bookstore

为什么在DOM解析的可视化表示中位于attr: "lang"上方element: <title>?纵观XML,它看起来像一个attr应该平行于其<element><book>category。这仅仅是节省空间的技术,还是要建立亲子关系?
1252748

这只是一种节省空间的技术
Premraj

3

DOM代表文档对象模型,它以树格式表示XML文档,每个元素代表树枝。DOM解析器创建XML文件的“内存中”树表示形式,然后对其进行解析,因此,它需要更多的内存,并且建议增加DOM解析器的堆大小,以避免Java.lang.OutOfMemoryError:java堆空间。如果XML文件很小,则使用DOM解析器解析XML文件的速度非常快,但是如果您尝试使用DOM解析器读取大型XML文件,则很可能会花费很长时间甚至无法完全加载它,这仅仅是因为创建XML Dom Tree需要大量内存。Java提供了对DOM解析的支持,您可以使用DOM解析器解析Java中的XML文件。DOM类位于w3c.dom包中,而DOM Parser for Java则位于JAXP(用于XML解析的Java API)包中。

Java中的SAX XML解析器

SAX代表XML解析的简单API。这是基于事件的XML解析,它逐步解析XML文件,因此非常适合大型XML文件。当SAX XML Parser遇到打开标签,元素或属性且相应地进行解析时,将触发事件。建议使用SAX XML解析器来解析Java中的大型xml文件,因为它不需要加载Java中的整个XML文件,并且可以一小部分地读取大型XML文件。Java提供了对SAX解析器的支持,您可以使用SAX解析器解析Java中的任何xml文件。在此,我已经介绍了使用SAX解析器读取xml文件的示例。在Java中使用SAX Parser的一个缺点是,与DOM Parser相比,使用SAX Parser读取Java中的XML文件需要更多代码。

DOM和SAX XML分析器之间的区别

以下是Java中DOM解析器和SAX解析器之间的一些高级差异:

1)DOM解析器将整个xml文档加载到内存中,而SAX仅将一小部分XML文件加载到内存中。

2)DOM解析器比SAX更快,因为它可以访问内存中的整个XML文档。

3)Java中的SAX解析器比DOM解析器更适合大型XML文件,因为它不需要太多内存。

4)DOM解析器可用于文档对象模型,而SAX是基于事件的xml解析器。

了解更多:http : //javarevisited.blogspot.com/2011/12/difference-between-dom-and-sax-parsers.html#ixzz2uz1bJQqZ


2

SAX和DOM都用于解析XML文档。两者都有优点和缺点,可以根据情况在我们的编程中使用

SAX:

  1. 逐节点解析

  2. 不将XML存储在内存中

  3. 我们无法插入或删除节点

  4. 上下移动

DOM

  1. 在处理之前将整个XML文档存储到内存中

  2. 占用更多内存

  3. 我们可以插入或删除节点

  4. 沿任何方向移动。

如果我们需要找到一个节点并且不需要插入或删除,则可以使用SAX本身,否则可以使用DOM,只要我们有更多的内存即可。


1

1)DOM解析器将整个XML文档加载到内存中,而SAX仅将XML文件的一小部分加载到内存中。

2)DOM解析器比SAX更快,因为它可以访问内存中的整个XML文档。

3)Java中的SAX解析器比DOM解析器更适合大型XML文件,因为它不需要太多内存。

4)DOM解析器可用于文档对象模型,而SAX是基于事件的XML解析器。

了解更多:http : //javarevisited.blogspot.com/2011/12/difference-between-dom-and-sax-parsers.html#ixzz498y3vPFR

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.