Last active
December 21, 2016 22:22
-
-
Save tvnpraveen/b35fc2a2dee2a5875cdc0c96736930a2 to your computer and use it in GitHub Desktop.
XML Comparison Library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module namespace xmlCompare = "http://lib/utils/xmlCompare"; | |
declare variable $xml1 := (); | |
declare variable $xml2 := (); | |
declare variable $idReference := (); | |
declare variable $resultMap := map:map(); | |
declare function xmlCompare:getPosition($node as node()){ | |
let $lastToken := fn:tokenize(xdmp:path($node),"[/]")[fn:last()] | |
return | |
if(fn:contains($lastToken,"[")) then | |
fn:tokenize(fn:tokenize($lastToken,"[\[]")[fn:last()],"[\]]")[1] | |
else() | |
}; | |
declare function xmlCompare:getPath($node as node()){ | |
fn:string-join(fn:tokenize(xdmp:path($node),"/")[3 to fn:last()],"/") | |
}; | |
declare function xmlCompare:processNode($node1 as node(), $node2 as node()) | |
{ | |
if(fn:not(fn:deep-equal($node1, $node2))) then | |
typeswitch($node1) | |
case text() | |
return | |
( | |
if(fn:normalize-space($node1) ne fn:normalize-space($node2)) then | |
map:put($resultMap,xdmp:path($node1)||","||fn:normalize-space($node1)||","||fn:normalize-space($node2),"") | |
else() | |
) | |
case element() | |
return | |
( | |
for $childNode1 in $node1/node() | |
return | |
if($childNode1 instance of text()) then | |
let $childNode2 := | |
xdmp:value("$node2/node()[fn:local-name(..) eq fn:local-name($childNode1/..)]")/fn:string() | |
return | |
if(fn:not(fn:exists($childNode2))) then | |
map:put($resultMap,xdmp:path($childNode1)||","||$childNode1||",","") | |
else( | |
if(fn:normalize-space($childNode1) ne fn:normalize-space($childNode2)) then | |
map:put($resultMap,xdmp:path($childNode1)||","||$childNode1||","||$childNode2,"") | |
else() | |
) | |
else( | |
let $localName := fn:local-name($childNode1) | |
let $id-elemName := $idReference/element-ref[element-name/text() eq $localName]/element-id/fn:string() | |
let $idNode := | |
if ($id-elemName) then | |
$childNode1/node()[fn:local-name(.) eq $id-elemName] | |
else() | |
let $id := $idNode/fn:string() | |
let $childNode2 := | |
if($id-elemName) then | |
( | |
xdmp:value("$node2/node()[node()/fn:local-name(.) eq $id-elemName][node()/fn:string() eq $id]") | |
) | |
else | |
( | |
let $childNode1Path := xmlCompare:getPath($childNode1) | |
return | |
xdmp:value("$xml2/"||$childNode1Path) | |
) | |
return( | |
if(fn:not(fn:exists($childNode2))) then | |
map:put($resultMap,xdmp:path($childNode1)||",Exists,Does Not Exist","") | |
else( | |
xmlCompare:processNode($childNode1,$childNode2) | |
) | |
) | |
) | |
) | |
default return () | |
else() | |
}; | |
declare function xmlCompare:compare($doc1, $doc2, $idRef) { | |
let $stripSpaceStyle := | |
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | |
<xsl:output method="xml" indent="yes" encoding="UTF-8"/> | |
<xsl:template match="@*|element( )"> | |
<xsl:copy> | |
<xsl:apply-templates select="@*|element( )|text()[ string-length(normalize-space(string(.))) gt 0 ]"/> | |
</xsl:copy> | |
</xsl:template> | |
</xsl:stylesheet> | |
let $_ := xdmp:set($xml1, xdmp:xslt-eval($stripSpaceStyle,$doc1/node())/element()) | |
let $_ := xdmp:set($xml2, xdmp:xslt-eval($stripSpaceStyle,$doc2/node())/element()) | |
let $_ := xdmp:set($idReference, $idRef/node()) | |
let $_ := xmlCompare:processNode($xml1, $xml2) | |
return | |
map:keys($resultMap) | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment