I have the following XML (Much of the data is dummy)
<?xml version="1.0" encoding="UTF-8"?>
<msg xmlns="http://someaddress.com/m1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://someaddress/somexsd.xsd">
<header>
<nodeA>aaaaaaaaaaa</nodeA>
<nodeB>bbbbbbbb</nodeB>
</header>
<payload>
<calcnode xmlns="http://someaddress/nodeC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://someaddress/somexsd.xsd">
<somefield>field</somefield>
</calcnode>
<ds:Signature>
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="#kjbn34jkb5j-3k45j-k3jb534jkb534k5">
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>+se0dfgft9gh8hjuji7ji65ko4ko3ko2</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>sekfrhsdkjfhsdkjfhksd</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>sdjkfhsdkfhskdf</X509Certificate>
</X509Data>
</KeyInfo>
</ds:Signature>
</payload>
</msg>
And all I want to do is change the name of the msg element (to newmsg) and the default namespace to http://someaddress.com/m2. Everything else should be kept as is. the closest I have been able to get is this xslt
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msg="http://someaddress.com/m1" >
<!-- the identity template -->
<xsl:template match="@* | node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<!-- replace namespace of elements in old namespace -->
<xsl:template match="msg:msg">
<xsl:element name="newmsg" namespace="http://someaddress.com/m2">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
I am using xalan for testing and this is the output xml I get when running the above
<?xml version="1.0" encoding="UTF-8"?>
<newmsg xmlns="http://someaddress.com/m2" xsi:schemaLocation="http://someaddress/somexsd.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<header xmlns="http://someaddress.com/m1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<nodeA>aaaaaaaaaaa</nodeA>
<nodeB>bbbbbbbb</nodeB>
</header>
<payload xmlns="http://someaddress.com/m1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<calcnode xmlns="http://someaddress/nodeC" xsi:schemaLocation="http://someaddress/somexsd.xsd">
<somefield>field</somefield>
</calcnode>
<ds:Signature>
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<Reference URI="#kjbn34jkb5j-3k45j-k3jb534jkb534k5">
<DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<DigestValue>+se0dfgft9gh8hjuji7ji65ko4ko3ko2</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>sekfrhsdkjfhsdkjfhksd</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>sdjkfhsdkfhskdf</X509Certificate>
</X509Data>
</KeyInfo>
</ds:Signature>
</payload>
</newmsg>
There are 2 main problems with this:
- The
dsnamespace simply disappears from the output and I don’t know why. - The second issue is that it drops the
xsinamespace from thecalcnodeand given that thecalcnodeis the node used to calculate (and verify) the signature (Which comes below that section) such change would make verification of the signature impossible to my understanding.
I have tried several different iterations of the xslt without much results. Could anybody shed some light in the situation?
This transformation:
when applied on the provided XML document:
produces the wanted, correct result: