Hello everyone this is the input XML and I want all the as it is XML structure inside a ns0:operationbody element. where opening < should be in entity form and > should be in '>' symbol.
Main problem is some extra namespaces are copying which are not in input XML child element
<?xml version = '1.0' encoding = 'UTF-8'?>
<root xmlns="GlobalInteraction.xsdobjects">
<ns1:Account xmlns:ns1="GlobalInteraction.xsdobjects">
<ns1:ExtReference>
<commonProvide:ExternalSystem xmlns:commonProvide="commonentities.xsdobjects.extload">BFG</commonProvide:ExternalSystem>
<commonProvide:ServiceElement2 xmlns:commonProvide="commonentities.xsdobjects.extload">
<!-- At this point no namespace is given but in output namespaces are displaying -->
**<commonProvide:ElementNumber>30</commonProvide:ElementNumber>
<commonProvide:PartNumber>60000283</commonProvide:PartNumber>**
</commonProvide:ServiceElement2>
</ns1:ExtReference>
<ns1:CustomerLegalName xmlns:ns1="GlobalInteraction.xsdobjects">CLARINS</ns1:CustomerLegalName>
<ns1:Type>Global</ns1:Type>
<ns1:SubType>National</ns1:SubType>
</ns1:Account>
</root>
After running the code this is the output:
<ns0:OperationBody xmlns:ns0="serviceBusiness.xsdobjects.extload.services.classic.bt"><root xmlns="GlobalInteraction.xsdobjects.extload">
<ns1:Account xmlns:ns1="GlobalInteraction.xsdobjects.extload">
<ns1:ExtReference xmlns:ns1="GlobalInteraction.xsdobjects.extload">
<commonProvide:ExternalSystem xmlns:commonProvide="commonentities.xsdobjects.extload" xmlns:ns1="GlobalInteraction.xsdobjects.extload">BFG</commonProvide:ExternalSystem>
</ns1:ExtReference>
<ns1:ExtReference xmlns:ns1="GlobalInteraction.xsdobjects.extload">
<commonProvide:ExternalSystem xmlns:commonProvide="commonentities.xsdobjects.extload" xmlns:ns1="GlobalInteraction.xsdobjects.extload">BFG</commonProvide:ExternalSystem>
<commonProvide:ServiceElement2 xmlns:commonProvide="commonentities.xsdobjects.extload" xmlns:ns1="GlobalInteraction.xsdobjects.extload">
<commonProvide:ElementNumber xmlns:commonProvide="commonentities.xsdobjects.extload" xmlns:ns1="GlobalInteraction.xsdobjects.extload">30</commonProvide:ElementNumber>
<commonProvide:PartNumber xmlns:commonProvide="commonentities.xsdobjects.extload" xmlns:ns1="GlobalInteraction.xsdobjects.extload">60000283</commonProvide:PartNumber>
</commonProvide:ServiceElement2>
</ns1:ExtReference>
<ns1:CustomerLegalName xmlns:ns1="GlobalInteraction.xsdobjects.extload">CLARINS</ns1:CustomerLegalName>
<ns1:Type xmlns:ns1="GlobalInteraction.xsdobjects.extload">Global</ns1:Type>
<ns1:SubType xmlns:ns1="GlobalInteraction.xsdobjects.extload">National</ns1:SubType>
</ns1:Account>
</root></ns0:OperationBody>
But requirement was I have to copy the whole input XML structure inside < and >. But we can see extra namespaces are copying in the element where it is not present Please suggest me any solution
Here is my XSLT:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="serviceBusiness.xsdobjects.extload" xmlns:ns1="GlobalInteraction.xsdobjects.extload"
xmlns:commonProvide="commonentities.xsdobjects.extload"
exclude-result-prefixes="xsl ns1 commonProvide">
<xsl:template match="/">
<ns0:OperationBody>
<xsl:apply-templates mode="escape"/>
</ns0:OperationBody>
</xsl:template>
<xsl:template match="*" mode="escape">
<!-- Begin opening tag -->
<xsl:text><</xsl:text>
<xsl:value-of select="name()"/>
<!-- Namespaces -->
<xsl:variable name="namespace-in" select="' xmlns="GlobalInteraction.xsdobjects.extload"'"/>
<xsl:variable name="namespace-ns1" select="' xmlns:ns1="GlobalInteraction.xsdobjects.extload"'"/>
<xsl:variable name="namespace-common" select="' xmlns:commonProvide="commonentities.xsdobjects.extload"'"/>
<xsl:if test="not(ancestor::*)">
<xsl:value-of select="$namespace-in"/>
</xsl:if>
<xsl:for-each select="namespace::*[name()='ns1' or name()='commonProvide']">
<xsl:choose>
<xsl:when test="name()='ns1'">
<xsl:value-of select="$namespace-ns1"/>
</xsl:when>
<xsl:when test="name()='commonProvide'">
<xsl:value-of select="$namespace-common"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
<!-- End opening tag -->
<xsl:text disable-output-escaping="yes">></xsl:text>
<!-- Content (child elements, text nodes, and PIs) -->
<xsl:apply-templates select="node()" mode="escape" />
<!-- Closing tag -->
<xsl:text></</xsl:text>
<xsl:value-of select="name()"/>
<xsl:text disable-output-escaping="yes">></xsl:text>
</xsl:template>
<xsl:template match="text()" mode="escape">
<xsl:call-template name="escape-xml">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="escape-xml">
<xsl:param name="text"/>
<xsl:if test="$text != ''">
<xsl:variable name="head" select="substring($text, 1, 1)"/>
<xsl:variable name="tail" select="substring($text, 2)"/>
<xsl:choose>
<xsl:when test="$head = '&'">&amp;</xsl:when>
<xsl:when test="$head = '<'">&lt;</xsl:when>
<xsl:when test="$head = '>'"><xsl:value-of select="'&gt;'" disable-output-escaping="yes"/></xsl:when>
<xsl:when test="$head = '"'">&quot;</xsl:when>
<xsl:when test="$head = "'"">&apos;</xsl:when>
<xsl:otherwise><xsl:value-of select="$head"/></xsl:otherwise>
</xsl:choose>
<xsl:call-template name="escape-xml">
<xsl:with-param name="text" select="$tail"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
CodePudding user response:
Your logic for processing namespaces is very strange. As far as I can see,
<xsl:for-each select="namespace::*[name()='ns1' or name()='commonProvide']">
<xsl:choose>
<xsl:when test="name()='ns1'">
<xsl:value-of select="$namespace-ns1"/>
</xsl:when>
<xsl:when test="name()='commonProvide'">
<xsl:value-of select="$namespace-common"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
is a rather long-winded way of writing
<xsl:if test="namespace::ns1">
<xsl:value-of select="$namespace-ns1"/>
</xsl:if>
<xsl:if test="namespace::commonProvide">
<xsl:value-of select="$namespace-common"/>
</xsl:if>
This isn't the immediate cause of the problem, although it provides a hint that you don't have a good understanding of how the namespace axis works.
The problem is that the namespace axis doesn't select the namespace declarations on an element, it selects all the in-scope namespaces for the element, including namespaces declared on parent elements. The way to eliminate the redundant namespaces is to test whether they're also present on the parent element:
<xsl:if test="namespace::ns1 and not(../namespace::ns1)">
etc