Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XSLT transformation changing namespaces

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:

  1. The ds namespace simply disappears from the output and I don't know why.
  2. The second issue is that it drops the xsi namespace from the calcnode and given that the calcnode is 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?

like image 381
Alexandre Thenorio Avatar asked May 22 '26 02:05

Alexandre Thenorio


1 Answers

This transformation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:oldDef="http://someaddress.com/m1" exclude-result-prefixes="oldDef">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="*">
  <xsl:element name="{name()}" namespace="{namespace-uri()}">
   <xsl:copy-of select="namespace::*[name()]|@*"/>
   <xsl:apply-templates select="node()"/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="*[namespace-uri()='http://someaddress.com/m1']">
  <xsl:element name="{name()}" namespace="http://someaddress.com/m2">
   <xsl:copy-of select="namespace::*[name()]"/>
   <xsl:copy-of select="@*"/>
   <xsl:apply-templates select="node()"/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="oldDef:msg[true()]">
  <newmsg xmlns="http://someaddress.com/m2">
   <xsl:copy-of select="namespace::*[name()]|@*"/>
   <xsl:apply-templates select="node()"/>
  </newmsg>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<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>

produces the wanted, correct result:

<newmsg xmlns="http://someaddress.com/m2" 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" 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>
like image 98
Dimitre Novatchev Avatar answered May 23 '26 14:05

Dimitre Novatchev