据我了解,通常在XSL中,每个节点可能只受一个模板的影响。一旦节点受到模板的影响,它 - 以及 - 至关重要的是它的子/后代 - 不会受到任何其他模板的影响。
但是,有时您希望使用一个模板影响外部节点,然后使用另一个模板影响其子/后代。以下是一个可取的方法吗?其目的是将属性'attr'添加到每个节点。
源XML: <根> <子> <孙子> < greatgrandchild>你好! < /孙子> < /儿童> < /根>
XSL:
<xsl:template match='node()'>
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match='child'>
<child>
<xsl:attribute name='attr'>val</xsl:attribute>
<xsl:apply-templates select='./*' />
</child>
</xsl:template>
<xsl:template match='greatgrandchild'>
<greatgrandchild>
<xsl:attribute name='attr'>val</xsl:attribute>
<xsl:value-of select='.' />
</greatgrandchild>
</xsl:template>
</xsl:stylesheet>
我是否在正确的位置?
提前致谢。
答案 0 :(得分:0)
坦率地说,是否处理节点完全取决于您的模板和内置模板(可以覆盖)。如果foo
元素节点的模板确实<xsl:apply-templates/>
,则处理子节点,如果它<xsl:apply-templates select="ancestor::*"/>
,则处理其祖先元素,只是给出两个示例。当然,如果您为某个不使用apply-templates
进行进一步处理的元素编写模板,则处理将停止。
对于您的示例,如果要向所有元素节点添加属性,那么您需要的只是
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="attr">val</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
标识转换模板加一个元素节点添加新属性。
答案 1 :(得分:0)
据我了解,通常在XSL中,每个节点可能只受一个节点的影响 模板。一旦节点受到模板的影响, 它 - 而且,至关重要的是,它的子女/后代 - 不会受到影响 进一步的任何其他模板。
这些陈述都不是真的。可以选择不同的模板在同一节点上执行 - 这一切都取决于导致选择特定模板以执行的<xsl:apply-templates>
指令。模板的应用和选择方式具有很大的灵活性,例如导入优先级,优先级,模式,......等。
甚至可以将模板制作成双节点(用作节点),就像在FXSL中一样。
但是,有时候,您希望使用一个模板影响外部节点, 然后使用另一个模板影响其子/后代。会的吗? 以下是一个可取的方法吗?它的目的是增加 将'attr'属性赋予每个节点。
使用最基本的XSLT设计模式 - 覆盖identity rule ,可以轻松实现这一点:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:variable name="val" select="count(ancestor::node())"/>
<xsl:copy>
<xsl:attribute name="depth">
<xsl:value-of select="$val"/>
</xsl:attribute>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档(更正为格式正确):
<root>
<child>
<grandchild>
<greatgrandchild>hello! </greatgrandchild>
</grandchild>
</child>
</root>
它复制每个节点并为每个元素添加depth
属性。新添加的属性的值是元素的“深度”:
<root depth="1">
<child depth="2">
<grandchild depth="3">
<greatgrandchild depth="4">hello! </greatgrandchild>
</grandchild>
</child>
</root>