0

I am trying to compare two xmls based on some node value.

Below are the two xmls:

a.xml

<?xml version="1.0"?>
<catalog>
    <cd>
        <Test>a</Test>
        <Test1>aa</Test1>
    </cd>
    <cd>
        <Test>e</Test>
        <Test1>ee</Test1>
    </cd>
    <cd>
        <Test>f</Test>
        <Test1>ff</Test1>
    </cd>
    <cd>
        <Test>c</Test>
        <Test1>cc</Test1>
    </cd>
</catalog>

b.xml

<?xml version="1.0"?>
<catalog>
    <cd>
        <Test>a</Test>
        <Test1>aa</Test1>
    </cd>
    <cd>
        <Test>b</Test>
        <Test1>bb</Test1>
    </cd>
    <cd>
        <Test>c</Test>
        <Test1>cc</Test1>
    </cd>
</catalog>

I am trying to compare the xmls using the content of Test as key.

Below is the xsl that I am using:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
    <xsl:key name="cd" match="cd" use="Test"/>
    <xsl:template match="/catalog">
        <!-- This is working -->
        <xsl:copy>
            <xsl:copy-of select="cd[Test=document('a.xml')/catalog/cd/Test]"/>
        </xsl:copy>
        <!--This is not working-->
        <xsl:copy>
            <xsl:copy-of select="cd[Test=key('cd', cd/Test, document('a.xml'))/Test]"/>
        </xsl:copy>
        <!--This is returning node-set-->
        <xsl:message>
            <xsl:copy-of select="document('a.xml')/catalog/cd/Test"/>
        </xsl:message>
        <!--This is returning node-set-->
        <xsl:message>
            <xsl:copy-of select="key('cd', cd/Test, document('a.xml'))/Test"/>
        </xsl:message>
    </xsl:template>
</xsl:stylesheet>

The output of the xsl should be common nodes in both xmls, based on Test node value.

But not sure why the one using xsl:key() function is not working. When I print it separately it is showing the correct node-set.

javaCurious
  • 140
  • 2
  • 14

1 Answers1

2

That behavior is explained because of those XPath/XSLT expressions in the context of catalog element:

  1. Without key: cd[Test=document('a.xml')/catalog/cd/Test]

Here you are going to select cd elements filtered by the predicate:

any of my Test childs has a string value equal to any of those Test elements in a.xml document

  1. With key: cd[Test=key('cd', cd/Test, document('a.xml'))/Test]

Here you are going to select cd elements filtered by the predicate:

any of my Test childs has a string value equal to any of those Test childs of the nodes that result from invoking the key named cd in the context of a.xml document with the string value of all my grandsons Test of all my childs cd

That last part will be an empty node set evaluated from the context of any cd element.

Alejandro
  • 1,882
  • 6
  • 13