2

I've got a mapping issue which I'm trying to solve in the mapping tool of BizTalk.

Consider the following input file:

<person>
    <ID>APersonID</ID>
    <relatives>
        <relative>
            <name>Relative name 1</name>
        </relative>
        <relative>
            <name>Relative name 2</name>
        </relative>
    </relatives>
</person>

Note: minOccurs of the relative element is set to 0 and the maxOccurs of the relative element is set to unbounded.

This input should be mapped to the following output:

<relatives>
    <person>
        <ID>APersonID</ID>
        <relative>Relative name 1</relative>
    </person>
    <person>
        <ID>APersonID</ID>
        <relative>Relative name 2</relative>
    </person>
<relatives>

Note: The person element has a minOccurs of 1 and a maxOccurs of unbounded.

I've got the mapping to work with a Looping functoid that links the relative element of the input file to the person element in the output file.But now there is a situation in which I'm given the following input file:

<person>
    <ID>APersonID</ID>
    <relatives />
</person>

Which should be mapped to

<relatives>
    <person>
        <ID>APersonID</ID>
    </person>
<relatives>

My current mapping can't handle this situation. Can somebody give suggestions on how to make/edit the mapping so that both situations can work?

SliverNinja - MSFT
  • 31,051
  • 11
  • 110
  • 173
Casper
  • 135
  • 1
  • 12

1 Answers1

2

Things are a bit more complex than at first seems since we need to test for existence of at least one relatives/relative before progressing. I can't think of any other way than to use XSLT - see here on how to extract the XSLT from your map and change the BTM to use an XSLT instead of the visual function mapping.

The following XSLT

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
    exclude-result-prefixes="msxsl var"
    version="1.0"
    xmlns:ns0="http://BizTalk_Server_Project5.Schema1">
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
    <xsl:template match="/">
        <xsl:apply-templates select="/ns0:person" />
    </xsl:template>
    <xsl:template match="/ns0:person">
        <relatives>
            <xsl:variable name="personId" select="ns0:ID/text()" />
            <xsl:choose>
                <xsl:when test="not(ns0:relatives) or not(ns0:relatives/ns0:relative)">
                    <person>
                        <ID>
                            <xsl:value-of select="$personId" />
                        </ID>
                    </person>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:for-each select="ns0:relatives/ns0:relative">
                        <person>
                            <ID>
                                <xsl:value-of select="$personId" />
                            </ID>
                            <relative>
                                <xsl:value-of select="ns0:name/text()" />
                            </relative>
                        </person>
                    </xsl:for-each>
                </xsl:otherwise>
            </xsl:choose>
        </relatives>
    </xsl:template>
</xsl:stylesheet>

Produces the output you've described. (Obviously change your namespaces to match, and I've assumed you've got elementFormDefault="qualified" (If not, drop the ns0 prefixes)

Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285