简体   繁体   中英

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

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.

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM