使用 XPaths 和 elementpath 库查找节点的第一次出现而不遍历所有节点
Find first occurence of node without traversing all of them using XPaths and elementpath library
我使用 elementpath 来处理一些 XPath 查询。我有一个具有线性结构的 XML
,其中包含一个独特的 id
属性。
<items>
<item id="1">...</item>
<item id="2">...</item>
<item id="3">...</item>
... 500k elements
<item id="500003">...</item>
</items>
我希望解析器在不遍历所有节点的情况下找到第一个出现的地方。例如,我想 select //items/item[@id = '3']
并在仅迭代 3 个节点(不超过 500k 个节点)后停止。对于许多情况来说,这将是一个很好的优化。
使用带有 XPath 静态参数的 XSLT 3 流式传输的示例,然后使用 xsl:iterate
和 xsl: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>
您可以 运行 使用 SaxonC 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)
我使用 elementpath 来处理一些 XPath 查询。我有一个具有线性结构的 XML
,其中包含一个独特的 id
属性。
<items>
<item id="1">...</item>
<item id="2">...</item>
<item id="3">...</item>
... 500k elements
<item id="500003">...</item>
</items>
我希望解析器在不遍历所有节点的情况下找到第一个出现的地方。例如,我想 select //items/item[@id = '3']
并在仅迭代 3 个节点(不超过 500k 个节点)后停止。对于许多情况来说,这将是一个很好的优化。
使用带有 XPath 静态参数的 XSLT 3 流式传输的示例,然后使用 xsl:iterate
和 xsl: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>
您可以 运行 使用 SaxonC 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)