Page 1 of 1

Add attribute to node

Posted: Mon May 13, 2019 11:52 am
by ferola
HI!
I am trying to transform a XML file using a XSLT. I made all the transformations required but I am not able to modify attributes in SOAP-ENV:ENVELOPE node.
I need to add some attributes to SOAP-ENV:Envelope node and to give the some value.
This is my XML:

Code: Select all

<?xml version="1.0"?><?xml-stylesheet href="myxsltfile.xsl" type="text/xsl"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>

<...GENERAL TAGS.../>

</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This is my XSLT (myxsltfile):

Code: Select all

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">

<xsl:template match="SOAP-ENV:Envelope">
	<xsl:copy>
      	<xsl:attribute name="xmlns:xmm">
      		<xsl:value-of select= "'http://namespace.com/xml/"/>
      	</xsl:attribute>
      	<xsl:attribute name="xmlns:xsd">
    		<xsl:value-of select= "'http://www.w3.org/2001/XMLSchema'"/>
    	</xsl:attribute>
      	<xsl:apply-templates select="@*"/>
		<xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
And this is the expected output:

<?xml version="1.0"?>
<?xml-stylesheet href="myxsltfile.xsl" type="text/xsl"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xmm= "http://namespace.com/xml/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
/>
<SOAP-ENV:Body>

<...GENERAL TAGS.../>

</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Any help is welcome! Thanks!

Re: Add attribute to node

Posted: Tue May 14, 2019 4:31 pm
by adrian
Hi,

Note that xmlns:xmm and xmlns:xsd are not valid attribute names so they cannot be used for xsl:attribute/@name. These are namespace prefix declarations, so you should treat them as such (not as attributes).
I see you are using an XSLT 1.0 stylesheet which is rather limiting given the requirements. Namespaces are far easier to handle with XSLT 2.0. Instead of xsl:attribute you could use (only with XSLT 2.0):

Code: Select all

<xsl:namespace name="xmm" select="'http://namespace.com/xml/'"/>
<xsl:namespace name="xsd" select="'http://www.w3.org/2001/XMLSchema'"/>
In XSLT 1.0 you can use a trick, but it requires that your XSLT 1.0 transformer supports the node-set extension function.
With what transformer or by what means are you planning to run this XSLT?
e.g. with Saxon 6.5.5

Code: Select all

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl">

    <xsl:template match="SOAP-ENV:Envelope">
        <xsl:variable name="nsprefixes">
            <xsl:element name="xmm:dummy" namespace="http://namespace.com/xml/"/>
            <xsl:element name="xsd:dummy" namespace="http://www.w3.org/2001/XMLSchema"/>
        </xsl:variable>
        <xsl:copy>
            <xsl:copy-of select="exsl:node-set($nsprefixes)//namespace::*"/>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="node() | @*">
        <xsl:copy>
            <xsl:apply-templates select="node() | @*"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
Regards,
Adrian