跳过Java中SAX解析中元素的内容

问题描述:

我正在解析Java应用程序中的自定义XML配置文件。我正在尝试使用SAX解析器,主要是因为我需要使用行号报告配置中的错误。跳过Java中SAX解析中元素的内容

有很多代码样本的网上实现处理类,事情似乎正常的处理相当简单的 - 例如,http://tutorials.jenkov.com/java-xml/sax-example.html

但在我的情况下,有时我需要跳过下的整个树元素:

<sampledocument> 
    <sampletag> 
     <process/> 
     <these/> 
     <tags/> 
    </sampletag> 
    <sampletag skip="yes"> 
     <do_not> 
     <process/> 
     <these/> 
     <tags/> 
    </sampletag> 
<sampledocument> 

后来增加:另外,我只知道是否在运行时跳过。在一定程度上人为的例子,我需要打开一个文件来处理<sampletag>下的标签,如果没有找到该文件,而不是对其进行处理:

<sampledocument> 
    <sampletag file="file1"> 
     <process/> 
     <these/> 
     <tags/> 
     <if_file1_exists/> 
    </sampletag> 
    <sampletag file="file2"> 
     <process/> 
     <these/> 
     <tags/> 
     <if_file2_exists/> 
    </sampletag> 
<sampledocument> 

当然,我可以跟踪在处理程序跳过代码,但这有点尴尬。我可以在startElement()方法中告诉SAX跳过这个元素的内容吗?

编写一个过滤器类,以便位于SAX解析器和现有ContentHandler之间的管道上。你可以通过扩展XMLFilterImpl来实现。这个过滤器应该有一个整数变量skipDepth,最初为零。

在startElement中,如果您识别想要深度跳过的元素,或者skipDepth> 0,则增加skipDepth。

在endElement中,如果skipDepth> 0,则递减skipDepth。

在所有事件处理程序,传递事件上下来的管道(通过调用super.xxx())当且仅当skipDepth == 0

如果你想聪明,你可以写这个过滤器以通用的方式,因此它需要一个参数,它是一个回调函数,它接受节点名称和属性并返回一个指示是否跳过该元素的布尔值。然后,您可以在下次想要跳过元素时重新使用代码,但跳过条件不同。

+0

谢谢!但是,与简单地维护ContentHandler中的skipDepth有什么不同?在我的真实任务中,ContentHandler必须在确定是否跳过树之前实际处理元素,因此如果我有单独的过滤器,则ContentHandler必须触发跳过。 –

+0

SAX代码总是最好写成一个管道,每个可分离任务的管道中只有一步。否则,你很快就会在ContentHandler中产生意大利面代码(你已经说过它“有点尴尬”)。通过正确构建的流水线,您最终得到易于修改和调试的可维护,可重用的代码;如果你把所有东西都放在ContentHandler中,你最终会得到不可维护的混乱。当然,如果你的例子与真实任务不同,那么我不能告诉你如何分解真正任务中的功能。 –

+0

我修改了示例以在运行时测试文件。真正的代码验证配置的正确性,解释它如何验证它会产生一个很长的问题,但它是对一个单独的类的调用 - 与检查文件有点类似。 –