问题描述
我编码了 XSLT 以通过验证属性值将一个节点数据复制到另一个节点,我得到了所需的输出,但我很想知道是否有一种有效的方法可以做到这一点,或者这是唯一的方法它。 [我不是 XSLT 专家] 有人可以帮忙吗!!!
请立即使用此链接进行检查。 https://xsltfiddle.liberty-development.net/pNvtBH2/3
实际 XML:
<?xml version="1.0" encoding="utf-8" ?>
<section>
<p>note 1 : <a href="test1">1</a></p>
<p>note 2 : <a href="test2">2</a></p>
<p>note 3 : <a href="test3">3</a></p>
<note id="test1">hello one</note>
<note id="test2">hello two</note>
<note id="test3">hello <i>three</i></note>
<note id="test4">hello <i>four</i></note>
</section>
输出:
<?xml version="1.0" encoding="UTF-8"?><section>
<p>note 1 : <a>hello one</a></p>
<p>note 2 : <a>hello two</a></p>
<p>note 3 : <a>hello <i>three</i></a></p>
<note id="test4">hello <i>four</i></note>
</section>
XSLT 代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output method="xml" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a">
<a>
<xsl:variable name="href" select="@href" />
<xsl:choose>
<xsl:when test="$href = //note/@id">
<xsl:copy-of select="//note[@id=$href]/node()" />
</xsl:when>
</xsl:choose>
</a>
</xsl:template>
<xsl:template match="note">
<xsl:choose>
<xsl:when test="@id = //a/@href">
<xsl:apply-templates select="node" />
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
解决方法
它是否有效取决于您的 XSLT 处理器中的优化器的智能程度。 Saxon-EE 会在这方面做得很好,Saxon-HE 不太好。
如果您想在所有处理器上都高效,请使用密钥。将 //note[@id=$href]
之类的表达式替换为对 key() 函数的调用。将密钥声明为
<xsl:key name="k" match="note" use="id"/>
然后您可以使用 key('k',$href)
获取匹配的节点。
xsl:when test="$href = //note/@id"
是多余的,因为如果没有选择任何内容,xsl:copy-of 将什么也不做。
在 note
模板中,我不确定是什么
<xsl:when test="@id = //a/@href">
<xsl:apply-templates select="node" />
</xsl:when>
正在尝试实现,因为您没有任何名为“node”的元素。如果目的是避免在此阶段处理已经从 a
元素处理过的音符元素,那么您可以使用
<xsl:key name="a" match="a" use="1"/>
并将 test="@id = //a/@href"
替换为 test="key('a',@href)"