XSLT从多个键中检索值?

时间:2017-09-05 13:07:23

标签: xslt xpath xslt-2.0

我有一个XML文件,我在其中查找多个键,然后用于查找更多元素。简化示例:检查他们喜欢的食物,然后将每种食物的成分添加为"购物清单"

<?xml version="1.0" encoding="UTF-8"?>
<foodieparadise>
    <people>
    <person name="Frank">
        <food>Cake</food>
        <food>Ice Cream</food>
        <food>Schnitzel</food>
    </person>
        <person name="Joe">
            <food>Steak</food>
            <food>Soup</food>
            <food>Schnitzel</food>
            <food>Ice Cream</food>
        </person>
    </people>

    <ingredients>
        <food name="Ice Cream">
            <ingredient>Ice</ingredient>
            <ingredient>Cream</ingredient>
        </food>
        <food name="Cake">
            <ingredient>Egg</ingredient>
            <ingredient>Flour</ingredient>
            <ingredient>Butter</ingredient>
            <ingredient>Cream</ingredient>
        </food>
        <food name="Schnitzel">
            <ingredient>Pork</ingredient>
            <ingredient>Bread Crumbs</ingredient>
        </food>
        <food name="Steak">
            <ingredient>Beef</ingredient>
        </food>
        <food name="Soup">
            <ingredient>Tomato</ingredient>
            <ingredient>Onions</ingredient>
            <ingredient>Parsley</ingredient>
            <ingredient>Egg</ingredient>
        </food>
    </ingredients>
</foodieparadise>

我使用这个XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output method="text" encoding="UTF-8" />

    <xsl:template match="/">
        <xsl:apply-templates select="/foodieparadise/people/person" />
    </xsl:template>

    <xsl:template match="person">
        <xsl:value-of select="@name"/> likes <xsl:value-of select="count(food)"/> types of food
and needs to buy <xsl:value-of select="count(distinct-values(/foodieparadise/ingredients/food/ingredient))"/> different ingredients.

    </xsl:template>

</xsl:stylesheet>

count(distinct-values(/foodieparadise/ingredients/food/ingredient))缺少每个人吃的食物的查询表达式。所以我得到了结果:

Frank likes 3 types of food and needs to buy 11 different ingredients.        
Joe likes 4 types of food and needs to buy 11 different ingredients.

但我需要实现的是:

Frank likes 3 types of food and needs to buy 7 different ingredients.        
Joe likes 4 types of food and needs to buy 8 different ingredients.

我试过了count(distinct-values(/foodieparadise/ingredients/food/ingredient[text() = ./food]))但是没有返回任何内容。

我的XPath和/或模板需要怎么样?

2 个答案:

答案 0 :(得分:2)

您需要的是:

count(distinct-values(/foodieparadise/ingredients/food[@name = current()/food]/ingredient))

答案 1 :(得分:1)

您也可以设置密钥

<xsl:key name="ref" match="ingredients/food" use="@name"/>

然后使用它

<xsl:template match="person">
    <xsl:value-of select="@name"/> likes <xsl:value-of select="count(food)"/> types of food
    and needs to buy <xsl:value-of select="count(distinct-values(key('ref', food)/ingredient))"/> different ingredients.

</xsl:template>