1
votes

The script which i'm trying with a source xml and the result is available in the below fiddle tool link

https://xsltfiddle.liberty-development.net/jxN9PRK/4

Source XML:

<root xmlns="http://www.oracle.com/retail/integration/rib/RibMessages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd">
   <parent>test</parent>
   <parentdtl>
   <child xmlns="http://test.com">
       <element1>1</element1>
   </child>   
   </parentdtl>
   <outer>T</outer>
</root> 

XSL Script used:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd"
    exclude-result-prefixes="#all"
    version="3.0">
  <xsl:template match="*">
        <xsl:variable name="copy-sans-namespaces" as="element()">
            <xsl:copy-of select="." copy-namespaces="no"/>
        </xsl:variable>
        <xsl:variable name="ser-params" as="element()">
            <output:serialization-parameters xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
                <output:omit-xml-declaration value="yes" />
            </output:serialization-parameters>
        </xsl:variable>
        <xsl:value-of select="serialize($copy-sans-namespaces, $ser-params)" />
    </xsl:template>
   <xsl:template match="*:root|*:parent|*:parentdtl|*:outer">
        <xsl:copy>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template> 
</xsl:stylesheet>

Expected OutPut:

<?xml version="1.0" encoding="UTF-8"?><root xmlns="http://www.oracle.com/retail/integration/rib/RibMessages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd">
   <parent>test</parent>
   <parentdtl>
   &lt;child xmlns="http://test.com"&gt;
       &lt;element1&gt;1&lt;/element1&gt;
   &lt;/child&gt;   
   </parentdtl>
   <outer>T</outer>
</root>

Instead i'm receiving the below result

<?xml version="1.0" encoding="UTF-8"?><root xmlns="http://www.oracle.com/retail/integration/rib/RibMessages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <parent>test</parent>
   <parentdtl>
   &lt;child xmlns="http://test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
       &lt;element1&gt;1&lt;/element1&gt;
   &lt;/child&gt;   
   </parentdtl>
   <outer>T</outer>
</root>

Facing two issues in the XSL script,

  1. XSL is including one of the namespace from root to its child while escaping. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" , but this should not be included while escaping the <child> node but the original namespace of <child> node should be retained in the conversion.

  2. The namespaces in the root is not all copied in the Result XML. xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd" is missed in the parent <root> node of resultant xml.

please share any pointers as i'm very new to XSLT. XSL version is 3.0 and using SAXON 9.6 engine in the project which i'm working on.

1
Please include the relevant samples of XML and XSLT and wanted and current output in your question here on StackOverflow. It doesn't suffice to link to an online sample. - Martin Honnen
Hi Martin, Please see the question updated with the details . - Prasanth
As far as I can tell, this is a quirk or bug in Saxon, I have asked on the Saxonica forum saxonica.plan.io/boards/3/topics/8011, let's hear what they think. I am not sure how to work around it for your input case, you could try to push your element(s) through a different mode where you use xsl:element instead of xsl:copy-of to recreate element nodes, that way the namespaces should not be copied. - Martin Honnen

1 Answers

0
votes

It seems the behaviour you get with Saxon 9.6 is a bug still present in Saxon 10.2, I enquired about it in https://saxonica.plan.io/boards/3/topics/8011 which lead to the bug issue https://saxonica.plan.io/issues/4793.

As a workaround, I guess you need to push your element through a node taking copies with xsl:element, avoiding namespace copying:

  <xsl:template match="*" mode="strip-in-scope-namespaces">
      <xsl:element name="{name()}" namespace="{namespace-uri()}">
          <xsl:copy-of select="@*"/>
          <xsl:apply-templates mode="#current"/>
      </xsl:element>
  </xsl:template>

  <xsl:template match="*">
        <xsl:variable name="copy-sans-namespaces" as="element()">
            <xsl:apply-templates select="." mode="strip-in-scope-namespaces"/>
        </xsl:variable>
      
        <xsl:variable name="ser-params" as="element()">
            <output:serialization-parameters xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
                <output:omit-xml-declaration value="yes" />
            </output:serialization-parameters>
        </xsl:variable>

        <xsl:value-of select="serialize($copy-sans-namespaces, $ser-params)" />
    </xsl:template>

https://xsltfiddle.liberty-development.net/jxN9PRK/5

As for xsi:schemaLocation missing, that is an attribute you forgot to copy; use

   <xsl:template match="*:root|*:parent|*:parentdtl|*:outer">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

https://xsltfiddle.liberty-development.net/jxN9PRK/6