我正在尝试解析是 xml
<a>
<b Number="first">
<c Over="1">
<name>1</name>
</c>
<c Over="2">
<name>2</name>
</c>
</b>
<b Number="Second">
<c Over="1">
<name>3</name>
</c>
<c Over="2">
<name>4</name>
</c>
</b>
</a>
使用分组概念
我喜欢这个
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
<xsl:key name="node-by-over" match="c" use="@Over" />
<xsl:template match="a">
<xsl:apply-templates select="b[@Number='first']/c[generate-id() = generate-id(key('node-by-over', @Over)[1])]"/>
</xsl:template>
<xsl:template match="c">
<table id="">
<xsl:for-each select="key('node-by-over', @Over)">
<tr>
<td>balls:::<xsl:value-of select="name"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
我的输出
<table><tr><td>balls:::1</td></tr><tr><td>balls:::3</td></tr></table><table><tr><td>balls:::2</td></tr><tr><td>balls:::4</td></tr></table>
预期
<table><tr><td>balls:::1</td></tr><tr><td>balls:::2</td></tr></table>
为什么它给出这样的输出 1,3,2,4 ???我已经在applytemplate
中使用了提及,我需要@Numberfirst
的所有节点c
<xsl:apply-templates select="b[@Number='first']/c[generate-id() = generate-id(key('node-by-over', @Over)[1])]"/>
预期输出 1,2(解析名称)
您的预期输出表明您希望:
- 仅包含每个组中的前
c/name
元素的列表 (按Over
属性分组), - 在单个
<table>
元素中。
(你应该在你的帖子中写过上面的内容)。
因此,对脚本的基本更改归结为以下内容:
<table>
移动到match="a"
模板。- 删除模板
match="c"
<xsl:for-each
(以生成输出) 仅针对当前组中的第一个元素)。
这是完整的脚本:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="node-by-over" match="c" use="@Over" />
<xsl:template match="a">
<table>
<xsl:apply-templates select=
"b[@Number='first']/c[generate-id() =
generate-id(key('node-by-over', @Over)[1])]"/>
</table>
</xsl:template>
<xsl:template match="c">
<tr><td>balls:::<xsl:value-of select="name"/></td></tr>
</xsl:template>
</xsl:stylesheet>
编辑
实际上不需要[@Number='first']
select
,因为分组仅从每个组中选择第一个c/name
元素(从整个文档中收集)。
或者,如果其他一些机制已经将元素分组(进入第一个和第二组,也许更多),然后基于key
的整个分组 不需要。 也许只要select="b[@Number='first']"
就足够了。