使用XSLT如何复制特定的XML子树
我已经找到了正确使用xsl:copy(XSLT1.0)的各种答案,但它们似乎都使用了相同的使用XSLT如何复制特定的XML子树,xml,xslt,Xml,Xslt,我已经找到了正确使用xsl:copy(XSLT1.0)的各种答案,但它们似乎都使用了相同的,可以很好地复制整个文档。我正在努力匹配一个特定的节点,我想复制并应用模板到它的子树 例如,给定此XML文档: <MyXML> <a> <b>c</b> </a> <d> <e>f</e> </d> <g x="y"> <foo bar="
,可以很好地复制整个文档。我正在努力匹配一个特定的节点,我想复制并应用模板到它的子树
例如,给定此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>
我想把
改成
或
可能很容易。我一直在猜测各种其他排列,但我无法得到我需要的结果。如果您只想处理foo
元素,只需添加一个与根节点匹配的模板,并将模板仅应用于所需的节点(从而删除所有其他节点):
XSLT1.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文档。标识模板(带有xsl:copy的模板)不仅复制整个文档:它复制您向其抛出的任何节点。具体地说,您“抛出一个节点”的方式是通过执行xsl:apply templates选择该节点。因此,可能您所缺少的只是根模板(match=“/”
)级别的
。我想我不明白匹配是如何工作的-所有xsl:template声明都有隐含的顺序吗?有没有办法说明这三个“扩展”是如何协同工作的?我的直觉让我认为每个声明都与上面的声明是串行工作的,这是错误的吗?我也不明白为什么在根(“/”)级别的匹配中需要额外的声明,以及为什么我不能只使用两个xsl:template声明。@Matt默认情况下,从根节点开始,然后从根节点向下推进-除非样式表介入。请记住,除非您重写它们,否则也会应用一些。在这种情况下,如果将这些元素留给它们处理,则会将b
和e
的文本节点复制到输出树中。
<foo bar="baz">
<item name="aname">quux</item>
<item name="bname">xYzzY</item>
</foo>
<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>