I’m looking for a way to select a unique set of nodes from an ancestor element below the root. My simplified input looks like this (Note: there may be several <Single> and <Multi> elements in a <Package>):
<Package>
<Single>
<Patient>
<Drug>
<Name>A</Name>
<Dose>1 tab</Dose>
</Drug>
<Drug>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>
</Drug>
</Patient>
</Single>
<Multi>
<Patient>
<Drug>
<Name>A</Name>
<Dose>1 tab</Dose>
</Drug>
<Drug>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>
</Drug>
<Drug>
<Name>C</Name>
<Dose>3 drops</Dose>
</Drug>
</Patient>
<Patient>
<Drug>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>
</Drug>
<Drug>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>
</Drug>
<Drug>
<Name>C</Name>
<Dose>3 drops</Dose>
</Drug>
<Drug>
<Name>D</Name>
<Dose>4 glasses</Dose>
</Drug>
</Patient>
</Multi>
</Package>
I’d like to select the Drugs that are unique for each <Single> or <Multi> element accross <Patient>s. So far I have:
<xsl:template match="/">
<xsl:for-each select="Package/Single | Package/Multi">
<xsl:call-template name="SO" />
</xsl:for-each>
</xsl:template>
<xsl:key name="uniqueKey" match="//Patient/Drug" use="concat(Name, Dose)" />
<xsl:template name="SO">
<UniquePerMultiOrSingle>
<xsl:for-each select="//Patient/Drug[
generate-id() =
generate-id(key('uniqueKey', concat(Name, Dose))[1])]">
<xsl:copy-of select="Name"/>
<xsl:copy-of select="Dose"/>
</xsl:for-each>
</UniquePerMultiOrSingle>
</xsl:template>
The output looks like this:
<UniquePerMultiOrSingle>
<Name>A</Name>
<Dose>1 tab</Dose>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>
<Name>C</Name>
<Dose>3 drops</Dose>
<Name>D</Name>
<Dose>4 glasses</Dose>
</UniquePerMultiOrSingle>
<UniquePerMultiOrSingle>
<Name>A</Name>
<Dose>1 tab</Dose>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>
<Name>C</Name>
<Dose>3 drops</Dose>
<Name>D</Name>
<Dose>4 glasses</Dose>
</UniquePerMultiOrSingle>
The desired output should look like this:
<UniquePerMultiOrSingle>
<Name>A</Name>
<Dose>1 tab</Dose>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>
</UniquePerMultiOrSingle>
<UniquePerMultiOrSingle>
<Name>A</Name>
<Dose>1 tab</Dose>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>
<Name>C</Name>
<Dose>3 drops</Dose>
<Name>D</Name>
<Dose>4 glasses</Dose>
</UniquePerMultiOrSingle>
My question: is there a way to select <Drug>s that are unique per <Single> or <Multi> element only (not the whole document)? If not, is there any other way to achieve this? I’m using xslt 1.0.
This transformation:
when applied on the provided XML document:
produces the wanted, correct result: