我有以下XML文档:
<root>
<object type="set">
<name>Test1</name>
<object type="set">
<name>Test11</name>
<object type="set">
<name>Test111</name>
</object>
</object>
</object>
<object type="set">
<name>Test2</name>
<object type="set">
<name>Test22</name>
</object>
</object>
<object type="set">
<name>Test3</name>
</object>
</root>
以及以下XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="//object[@type='set']">
<p>
<xsl:value-of select="name"/>
</p>
</xsl:template>
</xsl:stylesheet>
不知何故//对象[@type ='set']只选择第一个(Test1,Test2,Test3)。但我想选择所有元素(Test11,Test111,Test22)。
答案 0 :(得分:2)
模板永远不会“自行”实例化。
相反,模板仅应用于expression
指令上<xsl:apply-templates select="expression"/>
指定的节点列表。
另请注意,
<xsl:template match="//object[@type='set']">
相当于;
<xsl:template match="object[@type='set']">
再次 - 模板不选择 匹配。
此问题的一个解决方案:
使用:
<xsl:apply-templates select="//object[@type='set']"/>
整个转型变为:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="//object[@type='set']"/>
</body>
</html>
</xsl:template>
<xsl:template match="object[@type='set']">
<p>
<xsl:value-of select="name"/>
</p>
</xsl:template>
</xsl:stylesheet>
,它会产生想要的正确结果:
<html>
<body>
<p>Test1</p>
<p>Test11</p>
<p>Test111</p>
<p>Test2</p>
<p>Test22</p>
<p>Test3</p>
</body>
</html>
答案 1 :(得分:1)
另外,我想说你的xpath表达式确实匹配set类型的每个对象。
但是你必须要注意“set”类型的元素“object”可能包含同一类型的另一个元素的情况。在您的转换脚本中,您完全忽略了这一事实。
您只需复制属性“name”的第一个出现的值,并忽略它可能的子项。
您希望解决问题的方法可能是:
<xsl:template match="//object[@type='set']">
<p>
<xsl:value-of select="name"/>
</p>
<xsl:for-each select=".//object[@type='set']">
<p>
<xsl:value-of select="name"/>
</p>
</xsl:for-each></xsl:template>
相反,我更喜欢初始化xpath-expression的变量(nodeset),将其作为参数传递给相应的模板,并通过for-each遍历它。
希望我能帮忙,并为我糟糕的英语道歉:)
最好的问候