Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SAX解析器是如何工作的?_Java_Xml_Dom_Sax - Fatal编程技术网

Java SAX解析器是如何工作的?

Java SAX解析器是如何工作的?,java,xml,dom,sax,Java,Xml,Dom,Sax,我不熟悉XML解析。在执行一项需要解析大XML文件的任务时。因此,在尝试制作一个好的解决方案时,我遇到了这两个术语,DOM和SAX。这两种都是两种不同类型的XML解析。我在这里对SAX解析有点困惑。读了很多,但仍然感到困惑 让我们以下面的XML为例 <?xml version="1.0" encoding="UTF-8"?> <note> <Desc> <to>Tove</to> <from

我不熟悉XML解析。在执行一项需要解析大XML文件的任务时。因此,在尝试制作一个好的解决方案时,我遇到了这两个术语,DOM和SAX。这两种都是两种不同类型的XML解析。我在这里对SAX解析有点困惑。读了很多,但仍然感到困惑

让我们以下面的XML为例

 <?xml version="1.0" encoding="UTF-8"?>
<note>
     <Desc>
       <to>Tove</to>
       <from>Jani</from>
       <heading>Reminder</heading>
       <body>Don't forget me this weekend!</body>
     </Desc>
     <Desc>
       <to>Tove</to>
       <from>Jani</from>
       <heading>Reminder</heading>
       <body>Don't forget me this weekend!</body>
     </Desc>
     <Desc>
       <to>Tove</to>
       <from>Jani</from>
       <heading>Reminder</heading>
       <body>Don't forget me this weekend!</body>
     </Desc>
</note>

托弗
贾尼
提醒
这个周末别忘了我!
托弗
贾尼
提醒
这个周末别忘了我!
托弗
贾尼
提醒
这个周末别忘了我!
比方说,我只想让所有人都读所有的
标记并写入文件

我的疑问是:

  • 如果我使用DOM解析器,它会首先将所有xml加载到内存中,然后查找
    标记并写入文件吗

  • 如果我使用SAX解析器,它是否会首先在磁盘上查找
    标记本身,并在找到标记的那一刻开始读取,并一直加载到内存中,直到

  • 如果2个疑问是正确的,那么这种解读是如何发生的?SAX解析器是否逐字读取并将该字在内存中保留一段时间,并检查是否与代码要查找的标记匹配?因为标签的识别只能在内存中完成,但我认为这是不可能的。并保持单词从内存中下垂,直到找到所选的匹配项或标记。一旦找到它,它就开始在内存中保留所有单词,直到找到

  • 是否正确?
    请纠正我

    StAX(或pull解析器)将更好地适用于您描述的用例。 DOM读取整个文档,SAX解析器生成您需要处理的事件,它们不在内存中存储任何内容(内部除外)。使用SAX,您需要使用实现一个内容处理程序,这也意味着您需要维护事件流的状态。例如,您发布的文档的第一个区块将生成以下(简化)事件:

    因此,如果标记名为
    body
    (如果只需要
    note->Desc
    中的
    body
    元素,则需要在startElement中进行检查,并设置标志。在
    characters
    中,如果标志为true,则收集标记文本内容(或将其写入磁盘)。此外,在
    endElement
    中,需要将标志设置为false,以避免从其他标记收集字符。

    StAX(或pull解析器)将更好地适用于您描述的用例。 DOM读取整个文档,SAX解析器生成您需要处理的事件,它们不在内存中存储任何内容(内部除外)。使用SAX,您需要使用实现一个内容处理程序,这也意味着您需要维护事件流的状态。例如,您发布的文档的第一个区块将生成以下(简化)事件:


    因此,如果标记名为
    body
    (如果只需要
    note->Desc
    中的
    body
    元素,则需要在startElement中进行检查,并设置标志。在
    characters
    中,如果标志为true,则收集标记文本内容(或将其写入磁盘)。此外,在
    endElement
    中,需要将标志设置为false,以避免从其他标记收集字符。

    DOM解析器将整个XML文档加载到内存中,并通过Java API使其可用。这种方法的优点是易于使用和理解,但效率不高,因为:

    • 解析器必须读取整个XML文档并将其存储在内存中,即使您只想访问其中的一小部分
    • DOM解析器使用的数据结构(最有可能是哈希映射)是通用的,并且没有针对您的情况进行优化

    SAX解析器更难使用,但它的性能可能更高。SAX解析器在内存中不存储任何内容;相反,它调用您提供的代码来处理遇到的每个XML元素。在您的情况下,它会给您回电话说“我找到了!”然后说“我找到了!”等等。您如何处理这些事件取决于您,但通常您要么在内存中构建一些自定义Java对象,要么生成一个输出流。

    DOM解析器将整个XML文档加载到内存中,并通过Java API将其提供给您。这种方法的优点是易于使用和理解,但效率不高,因为:

    • 解析器必须读取整个XML文档并将其存储在内存中,即使您只想访问其中的一小部分
    • DOM解析器使用的数据结构(最有可能是哈希映射)是通用的,并且没有针对您的情况进行优化

    SAX解析器更难使用,但它的性能可能更高。SAX解析器在内存中不存储任何内容;相反,它调用您提供的代码来处理遇到的每个XML元素。在您的情况下,它会给您回电话说“我找到了!”然后是“我找到了!”等等。您如何处理这些事件取决于您,但通常您会在内存中构建一些自定义Java对象,或者生成一个输出流。

    当您说“我找到了”时,它会给您回电话说“我找到了!”!“然后”我发现了!,它在哪里求值?解析时,将从磁盘进行读取,并且它必须求值“我找到了”“内存中的某些内容本身..不是吗?假设您正在从磁盘读取,是的,XML将在磁盘上,回调将在内存中。”。但是SAX解析器将只在内存中保留当前正在读取的元素的相关信息。一旦它将该信息传递给您的程序,解析器就会忘记它。(好的,它必须在内存中保留一些额外的信息,以便跟踪它在文档中的位置,但开销很小。)这样考虑。
    startDocument
    startElement(note)
    startElement(Desc)
    startElement(to)
    characters(Tove) // might come as multiple chunks
    endElement(to)
    ...
    endDocument