Reputation: 37
This a follow-up from this stackoverflow question - Remove Duplicate Record from XML file using XLST
When using the online XSLT Test Tool (http://xslttest.appspot.com) the solution provided for this question works as expected. However when I implement the xslt into a shell script I receive the following error:
XPath error : Invalid expression
.[generate-id()=generate-id(key('DistinctEAN', @vchEAN)[1])]
^
compilation error: file titles_isbn.xsl line 15 element copy-of
xsl:copy-of : could not compile select expression '.[generate-id()=generate-id(key('DistinctEAN', @vchEAN)[1])]'
I do not understand why the xslt works fine when it is used in the XSLT Online Test Tool but not when it is used in a shell script format. Here is my shell script:
#!/bin/sh
echo "Renaissance Duplicate Filter Removal Script Start...."
cd /var/process/renaissance/scripts
xsltproc titles_isbn.xsl /var/process/renaissance/extractedfiles/titles_isbn_test.xml -o /var/process/renaissance/rrin/titles_isbn_nodup.xml
echo "Renaissance Duplicate Filter Removal Script complete"
Here is the titles_isbn.xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="DistinctEAN" match="z:row" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="RowsetSchema" use="@vchEAN" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="z:row" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="RowsetSchema" >
<xsl:copy-of select=".[generate-id()=generate-id(key('DistinctEAN', @vchEAN)[1])]"/>
</xsl:template>
</xsl:stylesheet>
Any help would be much appreciated.
Upvotes: 0
Views: 537
Reputation: 167736
I think XPath 1.0 has a quirk not allowing a predicate after the dot .
so use current()
instead of the dot.
As an alternative, simply put the negated condition in the match pattern of an empty template:
<xsl:template match="z:row[not(generate-id() = generate-id(key('DistinctEAN', @vchEAN)[1]))]" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="RowsetSchema"/>
Upvotes: 1
Reputation: 107767
Consider a standard Muenchian Grouping to remove duplicate records, compliant on most XSLT 1.0 processors.
Since I do not know your XML document structure, enter the placeholders for the grouping and matching nodes:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="DistinctEAN" match="[ENTERING MATCHING NODE]" use="@vchEAN" />
<!-- IdentityTransform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="[ENTER GROUPING NODE]">
<[ENTER GROUPING NODE]>
<xsl:for-each select="ENTER MATCHING NODE[generate-id()
= generate-id(key('DistinctEAN', @vchEAN)[1])]">
<[ENTER MATCHING NODE]>
<xsl:copy-of select="*"/>
</[ENTER MATCHING NODE]>
</xsl:for-each>
</[ENTERING GROUPING NODE]>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1