I can not figure out how to make this work using two files with xsltproc. cooking.xml is opened using document() and menu.xml is passed in on the command line. I can select the recipes without issue, what I can not figure out is how to get a unique list of ingredients. When I use the preceding-sibling function on my list of ingredients it behaves like this {[shell, beef, lettuce, tomato, cheese], [eggs, cheese]}. Why does a select like "cooking/recipe[@name = $menu]/ingredients" create a disjoint set that I can't use preceding-sibling on?
This is a contrived example from a larger system.
File cooking.xml
<?xml version="1.0" encoding="UTF-8"?>
<cooking xmlns="https://cooking.com/2022/cooking">
<recipe name="tacos">
<ingredient name="shell"/>
<ingredient name="beef"/>
<ingredient name="lettuce"/>
<ingredient name="tomato"/>
<ingredient name="cheese"/>
</recipe>
<recipe name="hamburger">
<ingredient name="bun"/>
<ingredient name="beef"/>
<ingredient name="lettuce"/>
<ingredient name="tomato"/>
</recipe>
<recipe name="omelet">
<ingredient name="eggs"/>
<ingredient name="cheese"/>
</recipe>
<recipe name="soup">
<ingredient name="chicken"/>
<ingredient name="stock"/>
</recipe>
</cooking>
File menu.xml
<?xml version="1.0" encoding="UTF-8"?>
<cooking xmlns="https://cooking.com/2022/cooking">
<recipe name="tacos"/>
<recipe name="omelet"/>
</cooking>
File shop.xsl
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:set="http://exslt.org/sets"
xmlns:cook="https://cooking.com/2022/cooking"
extension-element-prefixes="set">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:key name="rcp" match="recipe" use="@name" />
<xsl:template match="cooking">
<output>
<xsl:variable name="menu" select="recipe/@name" />
<!-- switch context to target document in order to use key -->
<xsl:for-each select="document('cooking.xml')">
<xsl:for-each select="set:distinct(key('rcp', $menu)/ingredient/@name)">
<ingredient name="{.}"/>
</xsl:for-each>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
xsltproc shop.xsl menu.xml >ingredients.xml
<?xml version="1.0" encoding="UTF-8"?>
<output xmlns:cook="https://cooking.com/2022/cooking"/>
Desired output:
<?xml version="1.0" encoding="UTF-8"?>
<cooking xmlns:cook="https://cooking.com/2022/cooking">
<ingredient name="shell"/>
<ingredient name="beef"/>
<ingredient name="lettuce"/>
<ingredient name="tomato"/>
<ingredient name="cheese"/>
<ingredient name="eggs"/>
</cooking>