Avbasot
Avbasot

Reputation: 363

Comparing a sequence of elements and replacing on match via XSLT/Xpath

I'm trying to do an intersect of sorts between two child elements in the same XML document.

<links>
 <old>
   <xref linkend="zzzzz">/chapter/subchapter[1]/section[2]/@id</xref>
   <xref linkend="aaaaa">/chapter/section[1]/@id</xref>
 </old>
 <new>
   <xref linkend="xxxxx">/chapter/subchapter[1]/section[2]/@id</xref>
   <xref linkend="sssss">/chapter/@id</xref>
 </new>
</links>

Whenever there is a match between the string path in new/xref and old/xref, I want to join the two elements and create an output like this:

<matches>
  <match old-linkend='zzzzz' new-linkend='xxxxx'>/chapter/subchapter[1]/section[2]/@id</match>
</matches>

This is my first attempt at comparing sequences so I'm a little lost. I am using XSLT 2.0 with Saxon.

Upvotes: 0

Views: 335

Answers (1)

Ian Roberts
Ian Roberts

Reputation: 122384

Starting from the context of one particular old/xref you can check for a matching new one with

<xsl:variable name="matching" select="../../new/xref[. = current()]"/>

In the square brackets, . is the new/xref you're testing and current() is the old/xref you started from. Checking whether this sequence is empty tells you whether or not there was a match.

<xsl:if test="$matching">
  <match old-linkend="{@linkend}" new-linkend="{$matching/@linkend}">
    <xsl:value-of select="." />
  </match>
</xsl:if>

If more than one new/xref matches this old/xref then the new-linkend attribute value template is subject to the rules for constructing simple content, which will concatenate the linkend values from all the matching new/xref elements together, separated by spaces.

Upvotes: 2

Related Questions