http://www.perlmonks.org?node_id=925873

gdanenb has asked for the wisdom of the Perl Monks concerning the following question:

Hi I've discovered that using XML::SemanticDiff is a little bit problematic when elements disordered.

Then I switched to XML::SemanticCompare but did not figure out a way to display the output of diff method in xml form.

Could somebody please post an example?

Replies are listed 'Best First'.
Re: diff output of XML::SemanticCompare
by toolic (Bishop) on Sep 14, 2011 at 14:04 UTC
    XML::SemanticCompare but did not figure out a way to display the output of diff method in xml form.
    Here is a quote from the XML::SemanticCompare POD:
    an array ref of strings representing the differences found between xml docs is returned. The strings look like XPATH statements but are not actual XPATH statements.
    How does the diff output vary from your expectation? Show a small snippet of what you get vs. what you expect. If you are expecting the output to be in the form of XML tags, that doesn't seem to be supported, according to my interpretation of the POD. (By the way, I tried installing it, but I gave up due to dependency errors.)
    XML::SemanticDiff is a little bit problematic when elements disordered
    You could submit a bug report. It is best to create as small a testcase as possible to demonstrate the problem you are having.

      I've read XML::SemanticCompare POD before using it.
      The output I get is like:

      /quartz[namespace-uri() = 'http://www.opensymphony.com/quartz/JobSched +ulingData']/job[namespace-uri() = 'http://www.opensymphony.com/quartz +/JobSchedulingData']/job-detail[namespace-uri() = 'http://www.opensym +phony.com/quartz/JobSchedulingData']/name[namespace-uri() = 'http://w +ww.opensymphony.com/quartz/JobSchedulingData']/text()=Distribution Co +ntent /quartz[namespace-uri() = 'http://www.opensymphony.com/quartz/JobSched +ulingData']/job[namespace-uri() = 'http://www.opensymphony.com/quartz +/JobSchedulingData']/job-detail[namespace-uri() = 'http://www.opensym +phony.com/quartz/JobSchedulingData']/description[namespace-uri() = 'h +ttp://www.opensymphony.com/quartz/JobSchedulingData']/text()=Updating + the distribution content with one message /quartz[namespace-uri() = 'http://www.opensymphony.com/quartz/JobSched +ulingData']/job[namespace-uri() = 'http://www.opensymphony.com/quartz +/JobSchedulingData']/job-detail[namespace-uri() = 'http://www.opensym +phony.com/quartz/JobSchedulingData']/job-class[namespace-uri() = 'htt +p://www.opensymphony.com/quartz/JobSchedulingData']/text()=com.cellti +ck.tasks.distributor.CCtDistributionContentJob /quartz[namespace-uri() = 'http://www.opensymphony.com/quartz/JobSched +ulingData']/job[namespace-uri() = 'http://www.opensymphony.com/quartz +/JobSchedulingData']/trigger[namespace-uri() = 'http://www.opensympho +ny.com/quartz/JobSchedulingData']/simple[namespace-uri() = 'http://ww +w.opensymphony.com/quartz/JobSchedulingData']/name[namespace-uri() = +'http://www.opensymphony.com/quartz/JobSchedulingData']/text()=Distri +bution Content Trigger /quartz[namespace-uri() = 'http://www.opensymphony.com/quartz/JobSched +ulingData']/job[namespace-uri() = 'http://www.opensymphony.com/quartz +/JobSchedulingData']/trigger[namespace-uri() = 'http://www.opensympho +ny.com/quartz/JobSchedulingData']/simple[namespace-uri() = 'http://ww +w.opensymphony.com/quartz/JobSchedulingData']/description[namespace-u +ri() = 'http://www.opensymphony.com/quartz/JobSchedulingData']/text() +=Triggers the broadcast task
      I thought that may be there is a way to convert it to xml tags, since I need to display a difference in readable format on screen.

      Regarding XML::SemanticDiff , I was sure that it's behavior is well known according http://ekawas.blogspot.com/2008_11_23_archive.html
      If I append new elements to the end of file, it's working great.
      But if some element is removed from begging of xml it displays a mess...

      I'd like to know if there is another way to display difference between two xml files...

        I thought that may be there is a way to convert it to xml tags, since I need to display a difference in readable format on screen.

        Of course there is a way, but you don't specify HOW it should be converted

        I'd like to know if there is another way to display difference between two xml files...

        Not using XML::SemanticCompare :)

        That is the format XML::SemanticCompare uses for comparison of likeness

        Its practically xpath, and hey, it is human readable, even if WIDE and vague :) its not meant for producing patches

        #!/usr/bin/perl -- use strict; use warnings; use XML::SemanticCompare; my $control = <<'__XML__'; <?xml version="1.0" encoding="UTF-8"?> <moby:MOBY xmlns:moby="http://www.biomoby.org/moby" xmlns:foobar="http +://www.biomoby.org/moby2"> <moby:mobyContent> <moby:mobyData moby:queryID="sip_1_"> <moby:Simple moby:articleName="allele"> <moby:Object moby:id="cho" moby:namespace="DragonDB_Allele"/> </moby:Simple> </moby:mobyData> </moby:mobyContent> </moby:MOBY> __XML__ my $test = <<'__XML__'; <?xml version="1.0" encoding="UTF-8"?> <moby:MOBY xmlns:moby="http://www.biomoby.org/moby" xmlns:foobar="http +://www.biomoby.org/moby2"> <moby:mobyContent> <moby:mobyData moby:queryID="sip_1_"> <moby:Simple moby:articleName="allele"> <moby:Object moby:id="cho" moby:namespace="DragonDB_Allele"/> </moby:Simple> <moby:Simple moby:articleName="allele2"> <moby:Object moby:id="CHI" moby:namespace="DragonDB_Allele">fo +o</moby:Object> </moby:Simple> </moby:mobyData> </moby:mobyContent> </moby:MOBY> __XML__ my $C = XML::SemanticCompare->new(); my $diffs_arrayref = $C->diff($control, $test) ; for ( my $ix = 0; $ix < $#$diffs_arrayref; $ix +=2 ){ my $a = $diffs_arrayref->[$ix]; my $b = $diffs_arrayref->[$ix+1]; print "Old: \n", fart($a),"\n", "New: \n", fart($b),"\n", "#" x 33, "\n"; } sub fart { local $_ = $_[0]; s{\'\]/}{']\n /}g; return $_; } __END__ Old: /MOBY[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyContent[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyData[namespace-uri() = 'http://www.biomoby.org/moby'] /Simple[namespace-uri() = 'http://www.biomoby.org/moby'] / New: /MOBY[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyContent[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyData[namespace-uri() = 'http://www.biomoby.org/moby'] /Simple[namespace-uri() = 'http://www.biomoby.org/moby'] /@[articleName='allele2' and namespace-uri() = 'http://www.biomoby +.org/moby'] ################################# Old: /MOBY[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyContent[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyData[namespace-uri() = 'http://www.biomoby.org/moby'] /Simple[namespace-uri() = 'http://www.biomoby.org/moby'] /Object[namespace-uri() = 'http://www.biomoby.org/moby'] / New: /MOBY[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyContent[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyData[namespace-uri() = 'http://www.biomoby.org/moby'] /Simple[namespace-uri() = 'http://www.biomoby.org/moby'] /Object[namespace-uri() = 'http://www.biomoby.org/moby'] /@[namespace='DragonDB_Allele' and namespace-uri() = 'http://www.b +iomoby.org/moby'] ################################# Old: /MOBY[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyContent[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyData[namespace-uri() = 'http://www.biomoby.org/moby'] /Simple[namespace-uri() = 'http://www.biomoby.org/moby'] /Object[namespace-uri() = 'http://www.biomoby.org/moby'] /@[id='CHI' and namespace-uri() = 'http://www.biomoby.org/moby'] New: /MOBY[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyContent[namespace-uri() = 'http://www.biomoby.org/moby'] /mobyData[namespace-uri() = 'http://www.biomoby.org/moby'] /Simple[namespace-uri() = 'http://www.biomoby.org/moby'] /Object[namespace-uri() = 'http://www.biomoby.org/moby'] /text()=foo #################################

        Take a close look at the source, its really not that complicated

        Esp see XML::SemanticCompare::SAX sub start_element

Re: diff output of XML::SemanticCompare
by Anonymous Monk on Sep 14, 2011 at 11:32 UTC
    What form should it take?
    use CGI; @outputFromSemanticCompare = qw/ a < a > a < a > /; print CGI->blockquote( qw[ now you're xml ], @outputFromSemanticCompare ) __END__ <blockquote>now you're xml a < a > a < a ></blockquote>