xsl-list
[Top] [All Lists]

Re: [xsl] How to compare two (possibly dissimilar) XML's (XSLT1.0)

2012-01-20 14:31:09
Hi Mark,

Assuming the element names are as given, and that hence each element has a unique name, probably the most straightforward approach would be to key the elements by retrieval using their names. This is largely because your requirements identify two elements as "the same" if they have the same name, and can ignore their positions in the document (at least until it comes to writing your reports).

For purposes of exposition, here's an XSLT 2.0 solution:

<xsl:key name="element-by-name" match="*" use="name()"/>

<xsl:variable name="B" select="document('wheredoyoufind/B.xml')"/>

Then you traverse A to report where elements are missing:

<xsl:template match="*">
  <xsl:if test="empty(key('element-by-name',name(),$B)">
     ... the element is missing from B ...
  </xsl:if>
  <xsl:apply-templates/>
</xsl:template>

Next to report if values are different. Since you only want to do this on leaf nodes, use a separate template to match only those:

<xsl:template match="*[empty(*)]">
  <xsl:if test=". != key('element-by-name',name(),$B)">
     ... A has a different value from B ...
  </xsl:if>
  <xsl:next-match/>
</xsl:template>

The next-match instruction here will (would) then apply the first template also to the elements that match the second one, so its test is also performed.

To rewrite this in XSLT 1.0, you have to do two things:

* Since key() can't take a third argument to define the scope of retrieval, you have to work extra to use the key on document B. So:

<xsl:template match="*">
  <xsl:variable name="n" select="name()"/>
  <xsl:for-each select="$B">
    <xsl:if test="not(key('element-by-name',$n)">
     ... the element is missing from B ...
    </xsl:if>
  </xsl:for-each>
  <xsl:apply-templates/>
</xsl:template>

Do similarly for the other template.

* Since xsl:next-match is not available in XSLT 1.0, work around this by giving the template matching * a name, which you can call (by name) from the other template.

I hope this helps.

Cheers,
Wendell

On 1/20/2012 1:57 PM, Mark Anderson wrote:
Hi Guys

I have an XML comparison XSL that works well for identical XML's; however, I 
need to create a version that will compare two slightly dissimilar XML's (whose 
structure I do not know--other than root element's name).

One will always be a superset of the other (if different).

For example

A contains

<elements>
     <element1>
         <element1a>1a</element1a>
         <element1b>1b</element1b>
         <element1c>1c</element1c>
     </element1>
     <element2>
         <element2a>2a</element2a>
         <element2b>2b</element2b>
         <element2c>2c</element2c>
     </element2>
     <element3>
         <element3a>3a</element3a>
         <element3b>3b</element3b>
         <element3c>3c</element3c>
     </element3>
</elements>


B Contains

<elements>
     <element1>
         <element1a>1a</element1a>
         <element1b>1b</element1b>
         <element1c>1c</element1c>
     </element1>
     <element3>
         <element3a>4a</element3a>
         <element3c>4c</element3c>
     </element3>
</elements>

I want to iterate through every element and attribute in A, find the 
corresponding element in B (if it exists) and compare their values.

For example, the output needs to indicate the following:

element2 is missing
element2/element2a is missing
element2/element2b is missing
element2/element2c is missing
element3/element3b is missing
element3a's value is different
element3b's value is different

Any help greatly appreciated


--
======================================================================
Wendell Piez                            
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
  Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>