I have an XML file where I lookup multiple keys that are then used to lookup more elements. Simplified examples: Check the food someone likes and then add up the ingredients for each of them as "shopping list"
<?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>
I use this 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>
The count(distinct-values(/foodieparadise/ingredients/food/ingredient))
is missing the query expression for the food each person eats. So I get the result:
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.
but what I need to achieve is:
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.
I tried count(distinct-values(/foodieparadise/ingredients/food/ingredient[text() = ./food]))
but that didn't return anything.
How would my XPath and/or template need to look like?
You could also set up a key
<xsl:key name="ref" match="ingredients/food" use="@name"/>
and then use it
<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>