I am assuming you want to output a Foo
element with a unique ID for each distinct FooName
in the input. For this, you could use the Muenchian method:
First you'd build a xsl:key
using which you can quickly retrieve FooName
elements by their content.
<xsl:key name="FooNames" match="FooName" use="."/>
Using this key, you can then process only the first instance of each FooName, thus getting a distinct list. Here you can make use of the generate-id()
function for comparing nodes for identity.
<xsl:apply-templates select="//FooName
[generate-id() =
generate-id(key('FooNames', .)[1])]"/>
For generating the identifiers, if you don't care that the generated identifiers may vary from run to run, you can again use the generate-id()
function.
Putting it all together:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="FooNames" match="FooName" use="."/>
<xsl:template match="/">
<Out>
<Foos>
<xsl:apply-templates select="//FooName[generate-id() =
generate-id(key('FooNames', .)[1])]"/>
</Foos>
<Bars>
<xsl:apply-templates select="//Input"/>
</Bars>
</Out>
</xsl:template>
<xsl:template match="FooName">
<Foo>
<Id><xsl:value-of select="generate-id()"/></Id>
<Name><xsl:value-of select="."/></Name>
</Foo>
</xsl:template>
<xsl:template match="Input">
<Bar>
<Id><xsl:value-of select="BarId"/></Id>
<Name><xsl:value-of select="BarName"/></Name>
<FooId>
<xsl:value-of select="generate-id(key('FooNames', FooName)[1])"/>
</FooId>
</Bar>
</xsl:template>
</xsl:stylesheet>
With the following sample input:
<Inputs>
<Input>
<BarId>123</BarId>
<BarName>myname</BarName>
<FooName>dummy</FooName>
</Input>
<Input>
<BarId>124</BarId>
<BarName>anothername</BarName>
<FooName>dummy</FooName>
</Input>
<Input>
<BarId>125</BarId>
<BarName>yetanothername</BarName>
<FooName>dummy-two</FooName>
</Input>
</Inputs>
It will yield the output:
<Out>
<Foos>
<Foo>
<Id>id213296</Id>
<Name>dummy</Name>
</Foo>
<Foo>
<Id>id214097</Id>
<Name>dummy-two</Name>
</Foo>
</Foos>
<Bars>
<Bar>
<Id>123</Id>
<Name>myname</Name>
<FooId>id213296</FooId>
</Bar>
<Bar>
<Id>124</Id>
<Name>anothername</Name>
<FooId>id213296</FooId>
</Bar>
<Bar>
<Id>125</Id>
<Name>yetanothername</Name>
<FooId>id214097</FooId>
</Bar>
</Bars>
</Out>