我有大约50MB到最大2GB的XML文件,其中只有一个文本节点的成千上万的mycomment
元素。到mycomment
节点的路径不是固定的,也没有定义,因此//mycomment
是获取所有路径的唯一方法。 mycomment/text()
的长度约为50到500个字符。我需要在所有mycomment
文本节点中搜索一种模式,以便对文件进行分类。如果在文本节点之一中找到模式" mypattern1234 "
,则变量hit
设置为1
,否则为空。这样计算hit
是一个好的解决方案:
<xsl:variable name="hit">
<xsl:if test="//mycomment[contains(text(),' mypattern1234 ')]">1</xsl:if>
</xsl:variable>
:-)我正在使用XSLT v1.0。谢谢。
[不清楚mycomment
元素是否可以具有混合内容或文本节点与注释或处理指令交织在一起。通常,如果您希望mycomment
元素仅具有文本内容,则可以选中mycomment[contains(., ' foo ')]
,而无需选择文本节点的子级。如果您想这样做,那么我将使用mycomment/text()[contains(., ' foo ')]
,您对text()
的检查作为contains
的参数将选择第一个文本子节点,因此例如<mycomment>foo <!-- a comment --> mypattern1234 </mycomment>
无法检测到文本。
关于效率,这将在很大程度上取决于所使用的XSLT处理器。
除非切换到流式XSLT 3.0处理器(如Saxon-EE,否则您将无法处理2GB的输入文档。
如果您使用的是流处理器,那么我建议这样做
<xsl:source-document href="input.xml" streamable="yes">
<xsl:if test="//text()[parent::comment][contains(.,' mypattern1234 ')]>1</xsl:if>
</xsl:source-document>
仅查看文本节点然后检查其上下文,而不是匹配元素节点然后设置对子文本节点的搜索,这会节省一些开销。
我希望2Gb搜索在大约一分钟内运行,具体取决于您的硬件。但是,一旦找到匹配项,就应停止对源文档的扫描,因此,如果在文档开头附近找到匹配项,它将比此过程快得多。