Xml 根据节点值对XPath查询进行分组?
我想知道是否存在这样一种情况,即能够基于元素中的文本对XML数据进行分组 我有一些类似于以下内容的XML,为了简单起见简化了:Xml 根据节点值对XPath查询进行分组?,xml,xslt,xpath,Xml,Xslt,Xpath,我想知道是否存在这样一种情况,即能够基于元素中的文本对XML数据进行分组 我有一些类似于以下内容的XML,为了简单起见简化了: <person> <name>Bob</name> <food>Apples</food> </person> <person> <name>Billy</name> <food>Bananas</food>
<person>
<name>Bob</name>
<food>Apples</food>
</person>
<person>
<name>Billy</name>
<food>Bananas</food>
</person>
<person>
<name>Bob</name>
<food>Oranges</food>
</person>
我使用了所有不同的示例尝试了多种方法,但我就是不能正确使用XPath。我只是无法集中精力只显示Bob的第一个实例,但也能够显示Bob的所有食物,这些食物分布在多个Bob实例中。关于从何处开始,您有什么建议吗?您可以使用XPath2(不使用xslt)执行类似的操作,使用不同的值获取所有名称,然后为每个名称创建包含食物的字符串
for $v in distinct-values(/person/name) return concat($v, ": ", string-join(/person[name = $v]/food, ", "))
返回(带有类型infos)
或更类似于您的输出:
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)
要使用xslt-1.0实现这一点,您应该查看Muenchian方法 因此,请尝试以下方法:
<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>
姓名:
个人食物:
你用谷歌搜索过“XSLT分组”吗?或者(我敢说)在XSLT教科书的索引中查找“分组”?是的,有大量关于这个主题的文献——对于XSLT1.0来说,这是一个相当棘手的问题(Muenchian分组),对于XSLT2.0来说,这是一个非常简单的问题(xsl:for each group)。
sequence: (string: Person's Name: Bob
Person's Food: Apples
Oranges, string: Person's Name: Billy
Person's Food: Bananas)
<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>