如果我运行以下XSLT代码:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kValueByVal" match="variable_name/@value"
use="."/>
<xsl:template match="assessment">
<xsl:for-each select="
/*/*/variable/attributes/variable_name/@value
[generate-id()
=
generate-id(key('kValueByVal', .)[1])
]
">
<xsl:value-of select=
"concat(., ' ', count(key('kValueByVal', .)), '
')"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
关于以下XML:
<assessment>
<variables>
<variable>
<attributes>
<variable_name value="FRED"/>
</attributes>
</variable>
</variables>
<variables>
<variable>
<attributes>
<variable_name value="MORTIMER"/>
</attributes>
</variable>
</variables>
<variables>
<variable>
<attributes>
<variable_name value="FRED"/>
</attributes>
</variable>
</variables>
</assessment>
我得到了所需的输出:
FRED 2
MORTIMER 1
(如果您愿意,请参阅my original question了解更多信息。)
但是,如果我在此输入上运行它:
<ExamStore>
<assessment>
<variables>
<variable>
<attributes>
<variable_name value="FRED"/>
</attributes>
</variable>
</variables>
<variables>
<variable>
<attributes>
<variable_name value="MORTIMER"/>
</attributes>
</variable>
</variables>
<variables>
<variable>
<attributes>
<variable_name value="FRED"/>
</attributes>
</variable>
</variables>
</assessment>
</ExamStore>
我一无所获。 (注意,我只是将原始输入包装在ExamStore标签中。)我期待并希望获得相同的输出。
为什么不呢?如何更改原始XSLT代码以获得相同的输出?
答案 0 :(得分:1)
您的选择xpath /*/*/variable/attributes/variable_name/...
不再正确,因为您在节点树中添加了另一个更高的节点。
如果你想拥有真正的独立性,你需要使用类似的东西:
//variable/attributes/variable_name/...
...(不是开头的双斜线),但这是相当危险的,因为它会捕捉到该结构的所有出现 - 确实是你的意思。
否则,只需将xpath添加到另一个/*
答案 1 :(得分:1)
当你在XML文档中引入了另一个级别时,这搞砸了原始解决方案中使用的绝对XPath表达式(完全在原始XML文件之后)。
因此,为了使XPath表达式在新的情况下工作,只需执行以下操作:
<强>替换强>:
/*/*/variable/attributes/variable_name/@value
<强>与强>
/*/*/*/variable/attributes/variable_name/@value
现在你又得到了想要的整洁结果:
FRED 2
MORTIMER 1
我永远不会给你一个“独立”的解决方案,因为你没有提供任何关于你想要应用转换的可能XML文档集的属性/保证/约束。
在您使用的原始问题中:
.//variables/variable/attributes/variable_name
关闭assessment
,
这就是我在我的解决方案中使用绝对XPath表达式的原因。无法保证在另一个XML文档中不会存在某些variable_name
元素,因此它们的祖先链不是variables/variable/attributes
,如果是这种情况,这意味着您可能对此不感兴趣这种“不规则”variable_name
元素的价值。
课程是在定义问题时不应过于具体,然后需要一般解决方案。 :)
答案 2 :(得分:0)
对于真实结构独立性,您应该使用:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:key name="kValueByVal" match="variable_name/@value"
use="."/>
<xsl:template match="variable_name[@value
[generate-id()
=
generate-id(key('kValueByVal', .)[1])
]]">
<xsl:value-of select=
"concat(@value, ' ', count(key('kValueByVal', @value)), '
')"/>
</xsl:template>
</xsl:stylesheet>
第一次输入的结果:
FRED 2
MORTIMER 1
第二次输入结果:
FRED 2
MORTIMER 1
注意:切勿将//
用作fisrt XPath运算符。