无法获得正确的XSLT输出
我有这样的XML:无法获得正确的XSLT输出
<?xml version="1.0" encoding="UTF-8"?>
<Section>
<Chapter>
<nametable>
<namerow>
<namecell stuff="1">
<entity>A</entity>
</namecell>
<namecell stuff="2">
<entity>B</entity>
</namecell>
</namerow>
</nametable>
</Chapter>
</Section>
我的XSLT是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:apply-templates select="Section/Chapter//nametable"/>
</xsl:template>
<xsl:template match="nametable">
<xsl:for-each select="./namerow">
<xsl:value-of select="./namecell/@stuff"/>
<xsl:value-of select="./namecell" />
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
奇是我得到的输出顺序1 2 AB,我以为我会得到1 A 2 B.
不知道为什么?
TIA,
约翰
你的问题是在这里:
<xsl:for-each select="./namerow">
<xsl:value-of select="./namecell/@stuff"/>
<xsl:value-of select="./namecell" />
</xsl:for-each>
不像在XSLT 1.0 XSLT 2.0中xsl:value-of
指令输出所有项在其select
属性中指定的序列组成。
这意味着
<xsl:value-of select="./namecell/@stuff"/>
输出所有stuff
属性(1和2)
则下一个指令:
<xsl:value-of select="./namecell" />
输出两个namecell
孩子的字符串值 - 分别为"A"
和"B"
。
解:
替换:
<xsl:for-each select="./namerow">
<xsl:value-of select="./namecell/@stuff"/>
<xsl:value-of select="./namecell" />
</xsl:for-each>
与:
<xsl:for-each select="./namerow">
<xsl:value-of select="./namecell/(@stuff|entity)"/>
</xsl:for-each>
的完整代码本变形例是:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:apply-templates select="Section/Chapter//nametable"/>
</xsl:template>
<xsl:template match="nametable">
<xsl:for-each select="./namerow">
<xsl:value-of select="./namecell/(@stuff|entity)"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
当这个变换应用所提供的XML文档:
<Section>
<Chapter>
<nametable>
<namerow>
<namecell stuff="1">
<entity>A</entity>
</namecell>
<namecell stuff="2">
<entity>B</entity>
</namecell>
</namerow>
</nametable>
</Chapter>
</Section>
想要的结果产生:
1 A 2 B
解决方法二(大概是什么你打算首先做):
更换:
<xsl:template match="nametable">
<xsl:for-each select="./namerow">
<xsl:value-of select="./namecell/@stuff"/>
<xsl:value-of select="./namecell" />
</xsl:for-each>
</xsl:template>
与:
<xsl:template match="nametable">
<xsl:for-each select="namerow/namecell">
<xsl:value-of select="@stuff"/>
<xsl:value-of select="entity"/>
</xsl:for-each>
</xsl:template>
现在你又得到了想要的结果:
1A2B
我使用MSXML,我越来越1 A
为OP:|
那么这里是为你解决它像宝石:)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<xsl:template match="/Section/Chapter/nametable/namerow/namecell">
<xsl:value-of select="@stuff"/>
<xsl:text> </xsl:text><!--inserting a space-->
<xsl:value-of select="entity"/>
<xsl:text> </xsl:text><!--inserting a space-->
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
这就是我所做的,以获得CORRE ct答案,我正在使用Saxon EE,但我不明白为什么我原来的帖子不能像它应该的那样工作。 – JohnX 2012-02-24 04:21:33
这可能是因为你正在使用'/ namecell/@ stuff'而不是'/ @ stuff' ..我没有真正专注于xslt 2.0所以不太确定.. – 2012-02-24 04:43:33
请参阅Dimitre的答案.. – 2012-02-24 04:46:48
的理由让你看到的行为是你遍历namerow。您将获得1A2B,如果您将代替名称单元重复:<xsl:for-each select="namerow/namecell"><xsl:value-of select="@stuff"/><xsl:value-of select="." /></xsl:for-each>
。您需要记住每个XPath(如@stuff
)不一定给出一个值(一个节点),而是一组值(一个节点集)。该集合通常会只包含一个值,但不会被愚弄。
另一种语法同样的事情:<xsl:for-each select="namerow"><xsl:for-each select="namecell"><xsl:value-of select="@stuff"/><xsl:value-of select="." /></xsl:for-each></xsl:for-each>
附:就像在文件系统路径中一样,您不必在XPath之前编写“./”。
合理。谢谢! – JohnX 2012-02-24 04:50:07
哦!这里是答案:) +1 – 2012-02-24 04:44:32
Dimitri:这是什么 真的吗? –
JohnX
2012-02-24 04:48:53
@JohnX:' '作为文本节点输出每个'namecell'的每个'stuff'属性和'entity'子元素的字符串值当前节点的子节点。在这里我使用Xpath * union *运算符'|'。在位置步骤中的这种联合只能在XPath 2.0中使用 - 在XPath 1.0中语法上是非法的。 –
2012-02-24 05:04:31