2

所以,我有一个像

<root>
  <transaction ts="1">
    <abc><def></def></abc>
  </transaction>
  <transaction ts="2">
    <abc><def></def></abc>
  </transaction>
</root>

所以,我有一个条件,如果 ts="2" 然后做某事......现在的问题是当它找到 ts="1" 它仍然扫描标签 <abc>< def> 然后到达 <transaction ts= "2">

有没有办法在条件不匹配解析中断时直接查找下一个事务标签?

4

4 回答 4

0

有没有办法在条件不匹配解析中断时直接查找下一个事务标签?

不,您必须编写 SAX 解析器才能知道何时跳过查看坏事务块中的标记。也就是说,您可能会发现切换到STAX比 SAX 更容易做这样的事情。

于 2013-08-05T18:14:04.027 回答
0

sax 解析器总是为每个 XML 元素调用您的回调。一旦检测到要忽略的条件,
您可以通过设置字段来解决您的问题。isIgnoreCurrentTransaction然后在其他 sax 回调中检查 isIgnoreCurrentTransactionamd 在这种情况下什么也不做。

于 2013-08-05T18:14:28.663 回答
0

您可以在 SAX 实现中使用控制标志,当您在某个标签上检测到您的条件时会引发该控制标志,并在您退出该标签后再次降低该标志。当解析器运行您不感兴趣的标签的子标签时,您可以使用该标志跳过任何处理。

但是请注意,您的示例 XML 无效。如注释中所述,您需要使用正确的标签嵌套,然后才能使用 SAX 实现对其进行处理。

于 2013-08-05T18:17:23.990 回答
0

SAX 解析器必须扫描所有子树(如您的“<abc>< def>< /def>< /abc>”)以了解下一个元素的开始位置。无法绕过它,这也是您无法为单个 XML 文档并行化 XML Parser 的原因。

在您的情况下,我能想到的唯一两种调整方式:

1) 如果您有许多 XML 文档要解析,您可以在其自己的线程中为每个文档运行一个 Parser。这至少可以并行化整个工作并利用所有可用的 CPU 和内核。

2)如果您只需要阅读某个条件(如您提到的 <transaction ts="2">),您可以在达到该条件后立即跳过解析。如果跳过解析器会有所帮助,那么解决方法是抛出异常。

您在startElement内部的实现ContentHandler将如下所示:

public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
    if(atts == null) return;
        if(localName.equals("transaction") && "2".equals(atts.getValue("ts"))) {
            // TODO: Whatever should happen when condition is reached
            throw new SAXException("Condition reached. Just skip rest of parsing");
        }
    }
于 2013-08-05T18:45:03.687 回答