SXI Forum

A place to collect usefull tips, tricks and implementation strategies.

You are not logged in.

#1 21-11-2018 18:24:40

SeanR
Administrator
Registered: 20-11-2018
Posts: 148

XSLT Stylesheets - Remove namespaces

This stylesheet removes namespaces from XML elements

<!-- Stylesheet to remove all namespaces from a document -->
<!-- NOTE: this will lead to attribute name clash, if an element contains
two attributes with same local name but different namespace prefix -->
<!-- Nodes that cannot have a namespace are copied as such -->

<!-- template to copy elements -->

<!-- template to copy attributes -->

<!-- template to copy the rest of the nodes -->

Offline

#2 24-11-2018 20:50:41

StephanB
Member
Registered: 21-11-2018
Posts: 39

Re: XSLT Stylesheets - Remove namespaces

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>
    
    <!-- Stylesheet to remove all namespaces from a document -->
    <!-- NOTE: this will lead to attribute name clash, if an element contains
        two attributes with same local name but different namespace prefix -->
    <!-- Nodes that cannot have a namespace are copied as such -->
    
    <!-- template to copy elements -->
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
    
    <!-- template to copy attributes -->
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>
    
    <!-- template to copy the rest of the nodes -->
    <xsl:template match="comment() | text() | processing-instruction()">
        <xsl:copy/>
    </xsl:template>
    
</xsl:stylesheet>

Offline

#3 30-06-2020 15:10:44

SeanR
Administrator
Registered: 20-11-2018
Posts: 148

Re: XSLT Stylesheets - Remove namespaces

When we convert a JSON object to an XML one there are a number of additional attributes that are included in order to show us what type of data in in the new XML element. E.g.  type="string".

Often we do not want to send these additional attributes to our clients and so remove them with a stylesheet.  However if we do not use the correct namespaces we end up with

xmlns=""

in the xml output.  This is because the child elements are in a different namespace from the parent.

E.g. The "OutputMemoryToLog" looks as follows:

<?xml version="1.0" encoding="UTF-8"?>
<XServiceBroker xmlns="http://www.sxi.co.za/XMLSchema">
  <payload>
    <Object xmlns="">
      <number type="string">INC0000123</number>
      <short_description xmlns="">ACME - Test 123</summary
      ...
     </Object>
  </payload>
</XServiceBroker>

When we apply the following stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>
    
    <xsl:template match="/">
        <data>
            <ref_num><xsl:value-of select="//*[local-name()='number']"/></ref_num>
            <summary><xsl:value-of select="//*[local-name()='short_description']"/></summary>
            ...
        </data>
    </xsl:template>
</xsl:stylesheet>

However after we have transformed the xml it looks as follows:

<?xml version="1.0" encoding="UTF-8"?>
<XServiceBroker xmlns="http://www.sxi.co.za/XMLSchema">
  <ref_num xmlns="">INC0000123</ref_num>
  <summary xmlns="">TCM - Test 123</summary>
  ...
</XServiceBroker>

To ensure your output does not have xmlns-"" in each element you need to add the xmlns="http://www.sxi.co.za/XMLSchema" declaration to your stylesheet.  This will create the new elements in the same namespace as the parent in the "OutputMemoryToLog" object.

<xsl:stylesheet version="1.0" xmlns="http://www.sxi.co.za/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>
    
    <xsl:template match="/">
        <data>
            <ref_num><xsl:value-of select="//*[local-name()='number']"/></ref_num>
            <summary><xsl:value-of select="//*[local-name()='short_description']"/></summary>
            ...
        </data>
    </xsl:template>
</xsl:stylesheet>

The result will now look correct:

<?xml version="1.0" encoding="UTF-8"?>
<XServiceBroker xmlns="http://www.sxi.co.za/XMLSchema">
  <ref_num>INC0000123</ref_num>
  <summary>ACME - Test 123</summary>
  ...
</XServiceBroker>

Offline

Board footer

Powered by FluxBB