Hope find a guru’s help to figure out the next problem.
I have two xml files. Firts one here (text.xml):
<text>
<ref>Author1, Title1, Date1</ref>
<ref>Author75, Title75, Date2</ref>
<ref>Author2, Title2, Date2</ref>
<ref>Author3, Title3, Date3</ref>
<text>
And the second one like this (list.xml):
<list>
<bibl xml:id="1"><author>Author1</author><date>Date1</date></bibl>
<bibl xml:id="2"><author>Author2</author><date>Date2</date></bibl>
<bibl xml:id="3"><author>Author3</author><date>Date3</date></bibl>
</list>
I want to query text.xml and check against list.xml to add @xml:id (from list.xml) to <ref> (from text.xml) wich contain same Author and Date. If not, then just copy original <ref>.
So I want to obtain:
<ref xml:id="1">Author1, Title1, Date1</ref>
<ref>Author75, Title75, Date2</ref>
<ref xml:id="2>Author2, Title2, Date2</ref>
etc.
My XSLT identify well all correpondence:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ref">
<xsl:variable name="ref" select="."/>
<xsl:for-each select="document('list.xml')//bibl">
<xsl:variable name="bibl" select="."/>
<xsl:variable name="author" select="author"/>
<xsl:variable name="date" select="date"/>
<xsl:choose>
<xsl:when test="contains($ref, $author) and contains($ref, $date)">
<ref>
<xsl:attribute name="xml:id">
<xsl:value-of select="$bibl/@xml:id"/>
</xsl:attribute>
<xsl:value-of select="$ref"/>
</ref>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$ref"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
But, then there aren’t correpondence it’s not just copy right <ref>, but copy all <ref> the number of time I have <bibl> nodes in the second file.
So problem is in <xsl:otherwise><xsl:copy-of select="$ref"/></xsl:otherwise>.
Any ideas how I can obtain only this distinct value I need? I know it’s must be very simple actually and I try key, generate-id, for-each-group, distinct-values, but can’t figure it out.
The problem is that you are creating a ref element for each iteration of the for-each loop whether there is a match or not.
What you need to do in this case is create the ref element outside of the for-each and then only create the id attribute for the matching element inside the loop
When applied to your sample XML, the following is output
However, your current method is not very efficient, as for each ref element you are iterating over all bibl elements. Another approach would be to extract the author and date from the ref elements, and then look up the bibl element directly
This should also give the same results.