
Untitled
By: a guest on
Apr 28th, 2012 | syntax:
None | size: 4.38 KB | hits: 15 | expires: Never
XSLT: How to select elements that are unique to an ancestor (not the root)?
<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>
<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>
<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>
<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>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kPackageDrugsByName" match="Drug"
use="concat(generate-id(../..), '+', Name, '+', Dose)"/>
<xsl:template match="Single | Multi">
<xsl:text>
</xsl:text>
<xsl:value-of select="name()"/> -- Drugs:
<xsl:text/>
<xsl:copy-of select=
"*/Drug
[generate-id()
=
generate-id(key('kPackageDrugsByName',
concat(generate-id(../..),
'+', Name, '+', Dose)
)[1]
)
]/*"/>
</xsl:template>
</xsl:stylesheet>
<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>
Single -- Drugs:
<Name>A</Name>
<Dose>1 tab</Dose>
<Name>B</Name>
<Dose>2 spoonfuls</Dose>
Multi -- Drugs:
<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>