我找到了有关正确使用 xsl:copy (XSLT 1.0) 的各种答案,但它们似乎都使用相同的 <xsl:template match="@*|node()">
这对于复制整个文档效果很好。我正在努力匹配我想要复制其子树并将模板应用到的特定节点。
例如,给定此 XML 文档:
<MyXML>
<a>
<b>c</b>
</a>
<d>
<e>f</e>
</d>
<g x="y">
<foo bar="baz">
<item name="aname">quux</item>
<item name="bname">xyzzy</item>
</foo>
</g>
</MyXML>
还有这个样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="item[@name='bname']/text()">
<xsl:value-of select="translate(current(), 'y', 'Y')" />
</xsl:template>
</xsl:stylesheet>
我想做的是仅复制元素 foo
及其属性和子节点,同时应用翻译“y”->“Y”。我想要的结果是这样的:
<foo bar="baz">
<item name="aname">quux</item>
<item name="bname">xYzzY</item>
</foo>
我认为这可能就像更改<xsl:template match="@*|node()">
一样简单至<xsl:template match="//foo">
或<xsl:template match="//foo/@*|//foo/node()">
。我一直在猜测各种其他排列,但无法得到我需要的结果。
最佳答案
如果您只想处理 foo
元素,您可以简单地添加一个与根节点匹配的模板,并将模板仅应用于您想要的节点(从而删除所有其他节点):
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="MyXML/g/foo"/>
</xsl:template>
<xsl:template match="item[@name='bname']/text()">
<xsl:value-of select="translate(., 'y', 'Y')" />
</xsl:template>
</xsl:stylesheet>
请注意,这假定最多有一个 foo
元素 - 否则结果将不是格式良好的 XML 文档。
关于xml - 使用 XSLT 如何复制特定的 XML 子树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44332758/