使用 XSLT 3.0 跳过第一个节点并复制其余节点
Skip first node and Copy rest of the nodes using XSLT 3.0
我需要跳过第一个 Worker
节点并使用 XSLT 3.0 复制其余节点
我的来源XML是
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Worker>
<Employee>Emp</Employee>
<ID>Identifier</ID>
</Worker>
<Worker>
<Employee>12344</Employee>
<ID>1245599</ID>
</Worker>
<Worker>
<Employee>25644</Employee>
<ID>7823565</ID>
</Worker>
</Workers>
并且期望的输出是
<?xml version="1.0" encoding="utf-8"?>
<Workers>
<Worker>
<Employee>12344</Employee>
<ID>1245599</ID>
</Worker>
<Worker>
<Employee>25644</Employee>
<ID>7823565</ID>
</Worker>
</Workers>
我拥有的 XSLT 是
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="Worker[position() = 1]"/>
</xsl:stylesheet>
上面的 XSLT 产生了我期望的输出,但我想看看是否有更好的方法来跳过第一个节点而不使用 postion()
,因为我不确定我当前代码的效率如何是处理大文件(大约 800 MB)
我不得不使用以下方法从我的结果中删除空格 XML
<xsl:strip-space elements="*"/>
任何人都可以检查我的代码并提供任何改进我的代码的建议吗?
===============
根据 Michael Kay 的建议,我的代码如下所示
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<!-- <xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template> -->
<!-- Removed above Identity Transformation -->
<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:template match="Workers">
<xsl:copy>
<xsl:apply-templates select="tail(Worker)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我会写的
<xsl:template match="Worker[1]"/>
为了可读性,但都是一样的。
带有位置谓词的匹配模式可能表现不佳,因此您要谨慎是对的,但像这样的简单模式应该没问题。事实上,主要的不利后果可能是 Saxon 将在 TinyTree 中分配 preceding-sibling 指针,以便它可以计算节点的兄弟位置。
Saxon 有效地将其实现为
<xsl:template match="Worker[not(preceding-sibling::Worker)]"/>
你可能更喜欢这样写。但是,这两种形式都不可流式传输。
要使其可流式传输,您可以通过不选择不需要的节点来删除它们:
<xsl:template match="Workers">
<xsl:copy>
<xsl:apply-templates select="tail(Worker)"/>
</xsl:copy>
</xsl:template>
在 non-streaming 的情况下也可能稍微快一些;它节省了内存,因为 preceding-sibling 不需要指针。
我需要跳过第一个 Worker
节点并使用 XSLT 3.0 复制其余节点
我的来源XML是
<?xml version="1.0" encoding="UTF-8"?>
<Workers>
<Worker>
<Employee>Emp</Employee>
<ID>Identifier</ID>
</Worker>
<Worker>
<Employee>12344</Employee>
<ID>1245599</ID>
</Worker>
<Worker>
<Employee>25644</Employee>
<ID>7823565</ID>
</Worker>
</Workers>
并且期望的输出是
<?xml version="1.0" encoding="utf-8"?>
<Workers>
<Worker>
<Employee>12344</Employee>
<ID>1245599</ID>
</Worker>
<Worker>
<Employee>25644</Employee>
<ID>7823565</ID>
</Worker>
</Workers>
我拥有的 XSLT 是
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="Worker[position() = 1]"/>
</xsl:stylesheet>
上面的 XSLT 产生了我期望的输出,但我想看看是否有更好的方法来跳过第一个节点而不使用 postion()
,因为我不确定我当前代码的效率如何是处理大文件(大约 800 MB)
我不得不使用以下方法从我的结果中删除空格 XML
<xsl:strip-space elements="*"/>
任何人都可以检查我的代码并提供任何改进我的代码的建议吗?
===============
根据 Michael Kay 的建议,我的代码如下所示
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" indent="yes"/>
<!-- <xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template> -->
<!-- Removed above Identity Transformation -->
<xsl:mode streamable="yes" on-no-match="shallow-copy"/>
<xsl:template match="Workers">
<xsl:copy>
<xsl:apply-templates select="tail(Worker)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我会写的
<xsl:template match="Worker[1]"/>
为了可读性,但都是一样的。
带有位置谓词的匹配模式可能表现不佳,因此您要谨慎是对的,但像这样的简单模式应该没问题。事实上,主要的不利后果可能是 Saxon 将在 TinyTree 中分配 preceding-sibling 指针,以便它可以计算节点的兄弟位置。
Saxon 有效地将其实现为
<xsl:template match="Worker[not(preceding-sibling::Worker)]"/>
你可能更喜欢这样写。但是,这两种形式都不可流式传输。
要使其可流式传输,您可以通过不选择不需要的节点来删除它们:
<xsl:template match="Workers">
<xsl:copy>
<xsl:apply-templates select="tail(Worker)"/>
</xsl:copy>
</xsl:template>
在 non-streaming 的情况下也可能稍微快一些;它节省了内存,因为 preceding-sibling 不需要指针。