In continuation of question "XSLT to Merge 2 XML Files" XSLT to Merge 2 XML Files
I have following doubts: 1) How to handle cases where nodes having same simple-path? 2) How to handle case where attribute have no element. I have tried executing provided xsl file (in referred link) with xml files where some attributes are empty then after merging, such attributes ends without ending quotient.
XML:1
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="D:\UNISON\UniSON_Rel2\R&D\test.xsl"?>
<NCP>
<NCPList>
<NCP ID="1" Label="LabelName">
<ParametersList>
<MasterControl>Enabled</MasterControl>
<ReservedPool></ReservedPool>
<Rule ID="1" Label="Label">
<RuleCriteria>
<CellType>Macro</CellType>
</RuleCriteria>
<Assignment>Enabled</Assignment>
<ReAssignment>Enabled</ReAssignment>
</Rule>
<Rule ID="2" Label="Label">
<RuleCriteria>
<CellType>Micro</CellType>
</RuleCriteria>
<Assignment>Enabled</Assignment>
<ReAssignment>Disabled</ReAssignment>
</Rule>
<Rule ID="3" Label="Label">
<RuleCriteria>
<CellType>Pico</CellType>
</RuleCriteria>
<Assignment>Enabled</Assignment>
<ReAssignment>Disabled</ReAssignment>
</Rule>
</ParametersList>
</NCP>
</NCPList>
</NCP>
XMl2:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="D:\UNISON\UniSON_Rel2\R&D\test.xsl"?>
<NCP>
<NCPList>
<NCP ID="1" Label="LabelName">
<ParametersList>
<MasterControl>Disabled</MasterControl>
<ReservedPool></ReservedPool>
<Rule ID="1" Label="Label">
<RuleCriteria>
<CellType>Macro</CellType>
</RuleCriteria>
<Assignment>Disabled</Assignment>
<ReAssignment>Disabled</ReAssignment>
</Rule>
<Rule ID="2" Label="Label">
<RuleCriteria>
<CellType>Micro</CellType>
</RuleCriteria>
<Assignment>Enabled</Assignment>
<ReAssignment>Disabled</ReAssignment>
</Rule>
</ParametersList>
</NCP>
</NCPList>
</NCP>
XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://ift.tt/tCZ8VR">
<xsl:output method="xml" indent="yes" />
<xsl:param name="aXmlPath" select="''" />
<xsl:param name="aDoc" select="document('q_xml2.xml')" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<!-- text nodes will be checked against doc A -->
<xsl:template match="*[not(*)]/text()">
<xsl:variable name="path">
<xsl:call-template name="calculatePath" />
</xsl:variable>
<xsl:variable name="valueFromA">
<xsl:call-template name="nodeValueByPath">
<xsl:with-param name="path" select="$path" />
<xsl:with-param name="context" select="$aDoc" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<!-- either there is something at that path in doc A -->
<xsl:when test="starts-with($valueFromA, 'found:')">
<!-- remove prefix added in nodeValueByPath, see there -->
<xsl:value-of select="substring-after($valueFromA, 'found:')" />
</xsl:when>
<!-- or we take the value from doc B -->
<xsl:otherwise>
<xsl:value-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- this calcluates a simpe path for a node -->
<xsl:template name="calculatePath">
<xsl:for-each select="..">
<xsl:call-template name="calculatePath" />
</xsl:for-each>
<xsl:if test="self::*">
<xsl:value-of select="concat(name(), '/')" />
</xsl:if>
</xsl:template>
<!-- this retrieves a node value by its simple path -->
<xsl:template name="nodeValueByPath">
<xsl:param name="path" select="''" />
<xsl:param name="context" select="''" />
<xsl:if test="contains($path, '/') and count($context)">
<xsl:variable name="elemName" select="substring-before($path, '/')" />
<xsl:variable name="nextPath" select="substring-after($path, '/')" />
<xsl:variable name="currContext" select="$context/*[name() = $elemName][1]" />
<xsl:if test="$currContext">
<xsl:choose>
<xsl:when test="contains($nextPath, '/')">
<xsl:call-template name="nodeValueByPath">
<xsl:with-param name="path" select="$nextPath" />
<xsl:with-param name="context" select="$currContext" />
</xsl:call-template>
</xsl:when>
<xsl:when test="not($currContext/*)">
<!-- always add a prefix so we can detect
the case "exists in A, but is empty" -->
<xsl:value-of select="concat('found:', $currContext/text())" />
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Please provide help in above doubts.
Thanks in advance
No comments:
Post a Comment