Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 根据节点值对XPath查询进行分组?_Xml_Xslt_Xpath - Fatal编程技术网

Xml 根据节点值对XPath查询进行分组?

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>

我想知道是否存在这样一种情况,即能够基于元素中的文本对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>

我使用了所有不同的示例尝试了多种方法,但我就是不能正确使用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>&#10;</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>&#10;</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>&#10;</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>&#10;</xsl:text>
            </xsl:for-each>

        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>