我想知道是否有能够根据元素内的文本对XML数据进行分组的事情。
我有一些类似于以下的XML,为简单而愚蠢:
<person>
<name>Bob</name>
<food>Apples</food>
</person>
<person>
<name>Billy</name>
<food>Bananas</food>
</person>
<person>
<name>Bob</name>
<food>Oranges</food>
</person>
我想以下列方式显示上述数据:
Person's Name: Bob
Person's Food: Apples
Oranges
Person's Name: Billy
Person's Food: Bananas
我尝试了使用所有不同示例的多种方法,但我无法正确使用XPath来实现这一目标。我只是无法绕过能够只显示Bob的第一个实例而且还能够显示Bob的所有食物,这些食物分布在Bob的多个实例中。关于我从哪里开始的任何建议?
答案 0 :(得分:2)
您可以使用XPath 2(不使用xslt)执行类似操作,使用distinct-values获取所有名称,然后使用每个名称的食物创建字符串。
for $v in distinct-values(/person/name) return concat($v, ": ", string-join(/person[name = $v]/food, ", "))
返回(使用类型信息)
sequence: (string: Bob: Apples, Oranges, string: Billy: Bananas)
或者更类似于您的输出:
for $v in distinct-values(/person/name) return concat(
"Person's Name: ", $v, "
Person's Food: ", string-join(/person[name = $v]/food, "
"))
返回
sequence: (string: Person's Name: Bob
Person's Food: Apples
Oranges, string: Person's Name: Billy
Person's Food: Bananas)
答案 1 :(得分:1)
要使用xslt-1.0执行此操作,您应该查看 Muenchian方法 e.g this
因此请尝试:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" method="text"/>
<xsl:key name="kPerson" match="person" use="name"/>
<xsl:template match="/*">
<xsl:for-each select="person[count( . | key('kPerson', name)[1]) =1 ]">
<xsl:variable name="pname" select="name" />
<xsl:text>Person's Name: </xsl:text>
<xsl:value-of select="$pname"/>
<xsl:text> </xsl:text>
<xsl:for-each select="key('kPerson', $pname)" >
<xsl:choose>
<xsl:when test="position()=1">Person's Food: </xsl:when>
<xsl:otherwise>
<xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="food"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>