How to copy a certain node (with children) from a XML with XSLT in Biztalk specifying a custom namespace?

StackOverflow https://stackoverflow.com//questions/9705891

  •  14-12-2019
  •  | 
  •  

Question

I need to copy a subnode from a XML to a certain node of a new XML in a Biztalk Map using XSLT.

Consider the following input XML:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:root xmlns:ns0="http://not/useful/data/">
    <ns0:notuseful>
        <ns0:foo></ns0:foo>
        <ns0:foo2></ns0:foo2>
        <ns0:blabla></ns0:blabla>
    </ns0:notuseful>
    <ns0:data>
        <ns1:usefulDataList xmlns:ns1="http://useful/data/">
            <ns1:usefulData>
                <ns1:usefulChild1></ns1:usefulChild1>
                <ns1:usefulChild2></ns1:usefulChild2>
                <ns1:usefulChild3></ns1:usefulChild3>
                <ns1:usefulChild4></ns1:usefulChild4>
                <ns1:usefulChild5></ns1:usefulChild5>
            </ns1:usefulData>
        </ns1:usefulDataList>
    </ns0:data>
<ns0:root>

What I need is to extract the node called "usefulDataList", so I need to copy it in a new XML like this one:

<?xml version="1.0" encoding="UTF-8"?>
<ns2:root2 xmln:ns2="http://new/xml">
    <ns2:blabla>
        <ns2:stuff />
    </ns2:blabla>
    <ns2:data>
        <ns2:usefulDataList>
            <ns2:usefulData>
                <ns2:usefulChild1></ns2:usefulChild1>
                <ns2:usefulChild2></ns2:usefulChild2>
                <ns2:usefulChild3></ns2:usefulChild3>
                <ns2:usefulChild4></ns2:usefulChild4>
                <ns2:usefulChild5></ns2:usefulChild5>
            </ns2:usefulData>
        </ns2:usefulDataList>
    </ns2:data>
</ns2:root2>

This should be done inside a Biztalk Functoid, as you see namespaces from source and target are diferent.

I'm an absolute beginner with XSLT, and I've been doing some tests, but I've something wrong with my XSLT expressions:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns2="http://new/xml">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
  <xsl:template name="testTemplate"  match="//*[local-name() = 'usefulDataList ']">
    <xsl:element name="ns0:usefulDataList " namespace="">
      <xsl:apply-templates mode="copy-no-ns" select="usefulDataList"/>
    </xsl:element>
  </xsl:template>
  <xsl:template mode="copy-no-ns" match="*">
    <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates mode="copy-no-ns"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

I'd appreciate any tip, with XSLT or Biztalk mapper. I don't like linking a huge amount of fields one by one if I can solve it with a XSLT expression.

Greetings.

Was it helpful?

Solution

Beware you had a space in *[local-name() = 'usefulDataList ']" so that would never match. this works:

<xsl:stylesheet version="1.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:ns2="http://new/xml">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

<xsl:template match="/">
 <ns2:root>
  <ns2:blabla>
   <ns2:stuff />
  </ns2:blabla>
 <ns2:data>
  <xsl:apply-templates mode="copy-no-ns" select="//*[local-name() = 'usefulDataList']"/>
 </ns2:data>
</ns2:root>
</xsl:template>
<xsl:template mode="copy-no-ns" match="*">
 <xsl:element name="ns2:{local-name(.)}">
  <xsl:copy-of select="@*"/>
  <xsl:apply-templates mode="copy-no-ns"/>
 </xsl:element>
</xsl:template>
</xsl:stylesheet>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top