[Home] [By Thread] [By Date] [Recent Entries]
Hi,
With XSLT 2.0 you can define a function to give you a unique value based on the location of a node inside the document and the value should be the same if the structure is identical. Then you can use a key to match the node in the master based on that value while you walk the nodes in your document. The stylesheet below gives you a result like: <?xml version="1.0" encoding="UTF-8"?><test> <nodeA attribute1="XXX" attribute1-diff="111" attribute2="YYY" attribute2-diff="222"> <nodeA1 diff="FFF">ZZZ</nodeA1> </nodeA> <nodeA attribute1="XXX" attribute2="YYY" attribute2-diff="ZZZ"> <nodeA1>ZZZ</nodeA1> </nodeA> <nodeB>AAA</nodeB> <nodeC>BBB</nodeC> <nodeC diff="BBB">BBC</nodeC> </test> when it is applied on a document with the content <?xml version="1.0" encoding="UTF-8"?>
<test>
<nodeA attribute1="XXX" attribute2="YYY">
<nodeA1>ZZZ</nodeA1>
</nodeA>
<nodeA attribute1="XXX" attribute2="YYY">
<nodeA1>ZZZ</nodeA1>
</nodeA>
<nodeB>AAA</nodeB>
<nodeC>BBB</nodeC>
<nodeC>BBC</nodeC>
</test>having a master.xml file in the same folder: <?xml version="1.0" encoding="UTF-8"?>
<test>
<nodeA attribute1="111" attribute2="222">
<nodeA1>FFF</nodeA1>
</nodeA>
<nodeA attribute1="XXX" attribute2="ZZZ">
<nodeA1>ZZZ</nodeA1>
</nodeA>
<nodeB>AAA</nodeB>
<nodeC>BBB</nodeC>
<nodeC>BBB</nodeC>
</test>Here it is the stylesheet: <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:x="http://www.oxygenxml.com/xslt/functions"> <xsl:function name="x:getPath"> <xsl:param name="node"/> <xsl:value-of select=" for $i in $node/ancestor-or-self::* return concat(local-name($i), count($i/preceding-sibling::*)) "/> </xsl:function> <xsl:key name="path" match="*" use="x:getPath(.)"/> <xsl:template match="*"> <xsl:variable name="id" select="x:getPath(.)"/> <xsl:variable name="this" select="."/> <xsl:variable name="master" select="document('master.xml')/key('path', $id)"/> <xsl:copy> <xsl:if test="not($master/text()=$this/text())"> <xsl:attribute name="diff" select="$master/text()"/> </xsl:if> <xsl:for-each select="@*"> <xsl:apply-templates select="."> <xsl:with-param name="master" select="$master/@*[name()=current()/name()]"/> </xsl:apply-templates> </xsl:for-each> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="@*"> <xsl:param name="master"/> <xsl:copy/> <xsl:if test="not(.=$master)"><xsl:attribute name="{name()}-diff" select="$master"/></xsl:if> </xsl:template> </xsl:stylesheet> Note that you can generate the diff attributes eventually in a specific namespace to avoid possible conflicts with existing attributes. Best Regards, George -- George Cristian Bina <oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger http://www.oxygenxml.com Mark Anderson wrote: Hi All
|

Cart



