#Hi everyone!
Would be grateful for some help in what feels like a slightly too steep learning curve ...
I have three files: '1b.xml', '2b.xml' and 'try.xcl'.
What I want to create is a number of xml and/or html files, each consisting of one of the instances found by the 'xsl:for-each', named after the @date and @id. I also need to use the 'class' value in 'bb' to select the matching 'class' values if both 'gg' and 'vv'.
I want the output to look like this:
<meny>
<mains>
<meat>chicken</meat>
<fish>trout</fish>
<vegetarian>moussaka</vegetarian>
</mains>
<extra>
<cake>Napoleon cake</cake>
<drinks>white</drinks>
</extra>
'try.xsl'
<xsl:template match="aa">
<xsl:variable name="doc2" select="document('2b.xml')"/>
<body>
<table>
<xsl:for-each select="bb">
<xsl:variable name="bb-num" select="@num"/>
<xsl:variable name="dd" select="$doc2/cc/dd[@id=$bb-num]"/>
<xsl:variable name="bb-class" select="@class"/>
<xsl:variable name="gg" select="$dd/ff/gg[@class=$bb-class]"/>
<xsl:variable name="vv" select="$dd/ff/vv[@class=$bb-class]"/>
<tr>
<td><xsl:value-of select="@date"/></td>
<td><xsl:value-of select="$dd/mm/ee"/></td>
<td><xsl:value-of select="$gg"/></td>
<td><xsl:value-of select="$vv"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</xsl:template>
'1b.xml':
<aa>
<bb date="31.12.2022" num="prs1" ></bb>
<bb date="07.01.2023" num="prs2" ></bb>
</aa>
'2b.xml':
<cc>
<dd id="prs1">
<mm>
<ee>steak</ee>
<nn>salmon</nn>
<oo>falaffel</oo>
</mm>
<ff>
<gg >carrot cake</gg>
<gg >chocolate cake</gg>
<gg >cream cake</gg>
<vv >red</vv>
<vv >white</vv>
<vv >sparkle</vv>
</ff>
</dd>
<dd id="prs2">
<mm>
<ee>chicken</ee>
<nn>trout</nn>
<oo>moussaka</oo>
</mm>
<ff>
<gg >Swiss roll</gg>
<gg >Napoleon cake</gg>
<gg >marzipan cake</gg>
<vv >red</vv>
<vv >white</vv>
<vv >sparkle</vv>
</ff>
</dd>
</cc>
CodePudding user response:
--- edited in response to clariifcation ---
In XSLT 2.0 or higher, you can do:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="dd" match="dd" use="@id" />
<xsl:key name="gg" match="gg" use="@class" />
<xsl:key name="vv" match="vv" use="@class" />
<xsl:template match="/aa">
<xsl:for-each select="bb">
<xsl:result-document href="{@date}-{@num}.xml">
<xsl:variable name="dd" select="key('dd', @num, document('2b.xml'))" />
<menu>
<mains>
<meat>
<xsl:value-of select="$dd/mm/ee" />
</meat>
<fish>
<xsl:value-of select="$dd/mm/nn" />
</fish>
<vegetarian>
<xsl:value-of select="$dd/mm/oo" />
</vegetarian>
</mains>
<extra>
<cake>
<xsl:value-of select="key('gg', @class, $dd)" />
</cake>
<drinks>
<xsl:value-of select="key('vv', @class, $dd)" />
</drinks>
</extra>
</menu>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Using your example inputs, this will create 2 result documents:
31.12.2022-prs1.xml
<menu>
<mains>
<meat>steak</meat>
<fish>salmon</fish>
<vegetarian>falaffel</vegetarian>
</mains>
<extra>
<cake>chocolate cake</cake>
<drinks>white</drinks>
</extra>
</menu>
07.01.2023-prs2.xml
<menu>
<mains>
<meat>chicken</meat>
<fish>trout</fish>
<vegetarian>moussaka</vegetarian>
</mains>
<extra>
<cake>Swiss roll</cake>
<drinks>red</drinks>
</extra>
</menu>
These results are different from the one you posted, nevertheless I believe they are correct.
P.S. The answer above is practically the same as the answer I gave to your previous question here. The adjustments are rather trivial and I wonder why you couldn't do them yourself.