我有一个XML文档,我接受了XSLT。结构类似于:
<root>
<item value="1">
<object/>
</item>
<item value="2" />
<object/>
</item>
</root>
我的目标是最终得到一个类似于:
的转换XML<root>
<parent>
<object-one value-one="1"/>
</parent>
<parent>
<object-two value-two="2"/>
</parent>
</root>
我的XSLT类似于:
<xsl:apply-templates select="object" />
<xsl:template match="object">
<xsl:call-template name="1" />
<xsl:call-template name="2" />
</xsl:template>
<xsl:template name="1" match="object[item/@value = '1'">
<xsl:element name="object-one" namespace="http://something.org">
<xsl:attribute name="_Description">
<xsl:value-of select="@_Type"/>
</xsl:attribute>
<xsl:attribute name="_Type">
<xsl:value-of select="@_Amount"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template name="2" match="object[item/@value = '2'">
<xsl:element name="object-two" namespace="http://something.org">
<xsl:attribute name="OriginalAmount">
<xsl:value-of select="@_Amount"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
问题是所有项目节点都应用了相同的模板。如何将模板仅应用于特定节点?
答案 0 :(得分:9)
编辑:现在针对不同的输入样本(针对格式正确的更正):
<root>
<item value="1">
<object/>
</item>
<item value="2" >
<object/>
</item>
</root>
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:num="number" extension-element-prefixes="num">
<num:num>one</num:num>
<num:num>two</num:num>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<parent>
<xsl:apply-templates/>
</parent>
</xsl:template>
<xsl:template match="object">
<xsl:variable name="vTextNumber" select="document('')/*/num:*[number(current()/../@value)]"/>
<xsl:element name="object-{$vTextNumber}">
<xsl:attribute name="value-{$vTextNumber}">
<xsl:value-of select="../@value"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
输出:
<root>
<parent>
<object-one value-one="1" />
</parent>
<parent>
<object-two value-two="2" />
</parent>
</root>
编辑2 :现在,样式表片段中出了什么问题?好吧,看起来你不知道处理器如何解决模板规则应用,也就是XPath navegation。
首先,此object[item/@value = '1']
仅匹配此类输入
<object>
<item value="1"/>
</object>
其次,考虑这三条规则
1 -
<xsl:template match="object">
</xsl:template>
2 -
<xsl:template name="1" match="object[../@value = '1']">
</xsl:template>
3 -
<xsl:template name="2" match="object[../@value = '2']">
</xsl:template>
使用上次提供的输入,第一个object
元素(按文档顺序)将匹配规则1和2,然后处理器将解析为应用规则2.为什么?来自http://www.w3.org/TR/xslt#conflict
接下来,所有匹配的模板规则 优先级低于匹配优先级 模板规则或规则 最高优先级被淘汰 考虑。一个优先权 模板规则由。指定 模板上的优先级属性 规则。这个价值必须是真实的 数字(正面或负面), 将生产数量与a匹配 可选的前导减号( - )。该 默认优先级计算为 如下:
- 如果模式包含由|分隔的多个替代项,那么它 等同于一组模板规则,每个模板规则一个 替代品。
- 如果模式的形式为QName,则前缀为
ChildOrAttributeAxisSpecifier或具有表单处理指令(Literal)
在ChildOrAttributeAxisSpecifier之前,优先级为0。- 如果模式的格式为NCName:*前面有一个
ChildOrAttributeAxisSpecifier,则优先级为-0.25。- 否则,如果模式只包含NodeTest 在ChildOrAttributeAxisSpecifier之前,优先级为-0.5。
- 否则,优先级为0.5。
答案 1 :(得分:0)
也许你可以让你的比赛更具体:
<xsl:template name="item1" match="item[@value=1]">
<xsl:element name="item" namespace="http://something.org">
<xsl:attribute name="_Description">
<xsl:value-of select="@_Type"/>
</xsl:attribute>
<xsl:attribute name="_Type">
<xsl:value-of select="@_Amount"/>
</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template name="item2" match="item[@value=2]">
<xsl:element name="item2_item" namespace="http://something.org">
<xsl:attribute name="OriginalAmount">
<xsl:value-of select="@_Amount"/>
</xsl:attribute>
</xsl:element>
</xsl:template>