I've got some XML, for example purposes it looks like this:
<root>
<field1>test</field1>
<f2>t2</f2>
<f2>t3</f2>
</root>
I want to transform it with XSLT, but I want to suppress the second f2 element in the output - how do I check inside my template to see if the f2 element already exists in the output when the second f2 element in the source is processed? My XSLT looks something like this at present:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no" omit-xml-declaration="yes" standalone="no" />
<xsl:template match="/">
<xsl:for-each select="./root">
<output>
<xsl:apply-templates />
</output>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" >
<xsl:element name="{name(.)}">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
I need to do some sort of check around the xsl:element in the template I think, but I'm not sure how to interrogate the output document to see if the element is already present.
Edit: Forgot the pre tags, code should be visible now!
It depends how system wide you want to be.
i.e. Are you only concerned with elements that are children of the same parent, or all elements at the same level ('cousins' if you like) or elements anywhere in the document...
In the first situation you could check the preceding-sibling axis to see if any other elements exist with the same name.
<xsl:if test="count(preceding-sibling::node()[name()=name(current())])=0">
... do stuff in here.
</xsl:if>
To only check (and warn you of a duplicate), you may find an example here
Something along the lines of:
<xsl:for-each-group select="collection(...)//@id" group-by=".">
<xsl:if test="count(current-group()) ne 1">
<xsl:message>Id value <xsl:value-of select="current-grouping-key()"/> is
duplicated in files
<xsl:value-of select="current-group()/document-uri(/)" separator=" and
"/></xsl:message>
</xsl:if>
</xsl:for-each-group>
To be modified to select all nodes within 'root' element.
As to remove the duplicate lines, you have another example here
That would look like:
<xsl:stylesheet>
<xsl:key name="xyz" match="record[x/y/z]" use="x/y/z" />
<xsl:variable name="noxyzdups" select="/path/to/record[generate-id(.) = generate-id(key('xyz', x/y/z))]" />
...
<xsl:template ... >
<xsl:copy-of "exslt:node-set($noxyzdups)" />
</xsl:template>
</xsl:stylesheet>
x/y/z is the xpath expression that you want made unique. It can be concat(x,'-',@y,'-',z) or whatever you want.
Now I am not sure those two examples can easily be adapted to your case, but I just wanted to point out those two sources, in case it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With