使用xpath和elementpath库查找第一个出现的节点,而不遍历所有节点



我使用elementpath来处理一些XPath查询。我有一个线性结构的XML,它包含一个唯一的id属性。

<items>
<item id="1">...</item>
<item id="2">...</item>
<item id="3">...</item>
... 500k elements
<item id="500003">...</item>
</items>

我希望解析器在不遍历所有节点的情况下找到第一个出现的节点。例如,我想选择//items/item[@id = '3'],并在迭代3个节点后停止(不超过500k个节点)。在许多情况下,这将是一个很好的优化。

使用带有XPath静态参数的XSLT 3流的示例,然后使用xsl:iteratexsl:break生成"提前退出";一旦找到了第一个搜索项,就会出现

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all">

<xsl:param name="path" static="yes" as="xs:string" select="'items/item[@id = ''3'']'"/>
<xsl:output method="xml"/>
<xsl:mode on-no-match="shallow-copy" streamable="yes"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:iterate _select="{$path}">
<xsl:if test="position() = 1">
<xsl:copy-of select="."/>
<xsl:break/>
</xsl:if>
</xsl:iterate>
</xsl:template>
</xsl:stylesheet>

你可以运行它与saxon EE(不幸的是流只支持EE)和Python,例如:

import saxonc
with saxonc.PySaxonProcessor(license=True) as proc:
print("Test SaxonC on Python")
print(proc.version)

xslt30proc = proc.new_xslt30_processor()
xslt30proc.set_parameter('path', proc.make_string_value('/items/item[@id = "2"]'))
transformer = xslt30proc.compile_stylesheet(stylesheet_file='iterate-items-early-exit1.xsl')

xdm_result = transformer.apply_templates_returning_value(source_file='items-sample1.xml')
if transformer.exception_occurred:
print(transformer.error_message)
print(xdm_result)

最新更新