none
Unable to Disassemble an XML RRS feed

  • Question

  • Hi,

    I try to disassemble en XML with Biztalk and the XMLReceive pipeline but I don't manage to get what i expected.

    I've an xml message like :

    ListKey>
    <key isvalid="true" id="2">
    <ListDateOk>
    <DateOk date="2015-08-20"/>
    </ListDateOk>
    </key>
    <key isvalid="false" id="3" />
    <key isvalid="true" id="4">
    <ListDateOk>
    <DateOk date="2015-08-21"/>
    <DateOk date="2015-08-22"/>
    <DateOk date="2015-08-23"/>
    </ListDateOk>
    </key>
    </ListKey>

    With no namespaces.

    And i expect something like :

    <key IsValid="true" id="2">
    <DateOk date="2015-08-20"/>
    </key>

    <key isvalid="false" id="3" />

    <key isvalid="true" id="4">
    <DateOk date="2015-08-21"/>
    </key>

    <key isvalid="true" id="4">
    <DateOk date="2015-08-22"/>
    </key>

    <key isvalid="true" id="4">
    <DateOk date="2015-08-23"/>
    </key>

    I'm a total beginner so I imagine that it's maybe very easy for most of you but can't figure out how to make it.

    Regards,

    J. BUN

    Tuesday, July 28, 2015 5:31 PM

Answers

  • Hi Jil22,

    To achieve desired result you will have to include root node in destination schema without root node u can achieve but it ll give you error like "there are multiple root node". for this you will have to use passthru in both side.

    Try below xslt.

    <?xml version="1.0" encoding="UTF-16"?>
    <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 userCSharp" version="1.0" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp">
      <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
      <xsl:template match="/">
        <xsl:apply-templates select="/ListKey" />
      </xsl:template>
      <xsl:template match="/ListKey">
        
        <Root>
          <xsl:for-each select="Key">
            
                <xsl:variable name="var:isvalid" select="@isvalid" />
                <xsl:variable name="var:id" select="@id" />
    
            <xsl:choose>
              <xsl:when test="@isvalid='true'">
                <xsl:for-each select="ListDateOk/DateOk">
                  <Key>
                    <xsl:attribute name="IsValid">
                      <xsl:value-of select="$var:isvalid" />
                    </xsl:attribute>
                    <xsl:attribute name="id">
                      <xsl:value-of select="$var:id" />
                    </xsl:attribute>
    
                    <xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(../../@isvalid) , &quot;true&quot;)" />
                    <xsl:if test="$var:v1">
                      <xsl:variable name="var:v2" select="string(../../@isvalid)" />
                      <xsl:variable name="var:v3" select="userCSharp:LogicalEq($var:v2 , &quot;true&quot;)" />
                      <DateOk>
                        <xsl:if test="string($var:v3)='true'">
                          <xsl:variable name="var:v4" select="@date" />
                          <xsl:attribute name="date">
                            <xsl:value-of select="$var:v4" />
                          </xsl:attribute>
                        </xsl:if>
                      </DateOk>
                    </xsl:if>
                </Key>
                </xsl:for-each>
              </xsl:when>
              <xsl:otherwise>
                <Key>
                  <xsl:attribute name="IsValid">
                    <xsl:value-of select="$var:isvalid" />
                  </xsl:attribute>
                  <xsl:attribute name="id">
                    <xsl:value-of select="$var:id" />
                  </xsl:attribute>
                </Key>
              </xsl:otherwise>
            </xsl:choose>
            
          </xsl:for-each>
        </Root>
      </xsl:template>
      <msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[
    public bool LogicalEq(string val1, string val2)
    {
    	bool ret = false;
    	double d1 = 0;
    	double d2 = 0;
    	if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
    	{
    		ret = d1 == d2;
    	}
    	else
    	{
    		ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0;
    	}
    	return ret;
    }
    
    
    public bool IsNumeric(string val)
    {
    	if (val == null)
    	{
    		return false;
    	}
    	double d = 0;
    	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
    }
    
    public bool IsNumeric(string val, ref double d)
    {
    	if (val == null)
    	{
    		return false;
    	}
    	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
    }
    
    
    ]]></msxsl:script>
    </xsl:stylesheet>


    Input Instance:

    <ListKey>
      <Key isvalid="true" id="2">
        <ListDateOk>
          <DateOk date="2015-08-20" />
        </ListDateOk>
      </Key>
      <Key isvalid="false" id="3"/>
      <Key isvalid="true" id="4">
        <ListDateOk>
          <DateOk date="2015-08-21" />
        <DateOk date="2015-08-22" />
       <DateOk date="2015-08-23" />
        </ListDateOk>
      </Key>
    </ListKey>

    OutPut Instance:

    <Root>
    <Key IsValid="true" id="2">
    <DateOk date="2015-08-20"></DateOk>
    </Key>
    <Key IsValid="false" id="3">
    </Key>
    <Key IsValid="true" id="4">
    <DateOk date="2015-08-21"></DateOk>
    </Key>
    <Key IsValid="true" id="4">
    <DateOk date="2015-08-22"></DateOk>
    </Key>
    <Key IsValid="true" id="4">
    <DateOk date="2015-08-23"></DateOk>
    </Key>
    </Root>

    It will help you.



    Kind Regards, Anurag Prajesh (BizTalk Developer)


    Thursday, July 30, 2015 6:36 AM

All replies

  • Hi BUN,

    I think it is not  possible with XML disAssemble component.

    You need to implement the logic in mapping,You can write an XSLT to Achieve this.

    Thanks&Regards,

    Ammu4Biz.


    • Proposed as answer by Shankycheil Wednesday, July 29, 2015 4:42 AM
    Tuesday, July 28, 2015 5:42 PM
  • Hi Jil22,

    To achieve desired result you will have to include root node in destination schema without root node u can achieve but it ll give you error like "there are multiple root node". for this you will have to use passthru in both side.

    Try below xslt.

    <?xml version="1.0" encoding="UTF-16"?>
    <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 userCSharp" version="1.0" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp">
      <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
      <xsl:template match="/">
        <xsl:apply-templates select="/ListKey" />
      </xsl:template>
      <xsl:template match="/ListKey">
        
        <Root>
          <xsl:for-each select="Key">
            
                <xsl:variable name="var:isvalid" select="@isvalid" />
                <xsl:variable name="var:id" select="@id" />
    
            <xsl:choose>
              <xsl:when test="@isvalid='true'">
                <xsl:for-each select="ListDateOk/DateOk">
                  <Key>
                    <xsl:attribute name="IsValid">
                      <xsl:value-of select="$var:isvalid" />
                    </xsl:attribute>
                    <xsl:attribute name="id">
                      <xsl:value-of select="$var:id" />
                    </xsl:attribute>
    
                    <xsl:variable name="var:v1" select="userCSharp:LogicalEq(string(../../@isvalid) , &quot;true&quot;)" />
                    <xsl:if test="$var:v1">
                      <xsl:variable name="var:v2" select="string(../../@isvalid)" />
                      <xsl:variable name="var:v3" select="userCSharp:LogicalEq($var:v2 , &quot;true&quot;)" />
                      <DateOk>
                        <xsl:if test="string($var:v3)='true'">
                          <xsl:variable name="var:v4" select="@date" />
                          <xsl:attribute name="date">
                            <xsl:value-of select="$var:v4" />
                          </xsl:attribute>
                        </xsl:if>
                      </DateOk>
                    </xsl:if>
                </Key>
                </xsl:for-each>
              </xsl:when>
              <xsl:otherwise>
                <Key>
                  <xsl:attribute name="IsValid">
                    <xsl:value-of select="$var:isvalid" />
                  </xsl:attribute>
                  <xsl:attribute name="id">
                    <xsl:value-of select="$var:id" />
                  </xsl:attribute>
                </Key>
              </xsl:otherwise>
            </xsl:choose>
            
          </xsl:for-each>
        </Root>
      </xsl:template>
      <msxsl:script language="C#" implements-prefix="userCSharp"><![CDATA[
    public bool LogicalEq(string val1, string val2)
    {
    	bool ret = false;
    	double d1 = 0;
    	double d2 = 0;
    	if (IsNumeric(val1, ref d1) && IsNumeric(val2, ref d2))
    	{
    		ret = d1 == d2;
    	}
    	else
    	{
    		ret = String.Compare(val1, val2, StringComparison.Ordinal) == 0;
    	}
    	return ret;
    }
    
    
    public bool IsNumeric(string val)
    {
    	if (val == null)
    	{
    		return false;
    	}
    	double d = 0;
    	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
    }
    
    public bool IsNumeric(string val, ref double d)
    {
    	if (val == null)
    	{
    		return false;
    	}
    	return Double.TryParse(val, System.Globalization.NumberStyles.AllowThousands | System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out d);
    }
    
    
    ]]></msxsl:script>
    </xsl:stylesheet>


    Input Instance:

    <ListKey>
      <Key isvalid="true" id="2">
        <ListDateOk>
          <DateOk date="2015-08-20" />
        </ListDateOk>
      </Key>
      <Key isvalid="false" id="3"/>
      <Key isvalid="true" id="4">
        <ListDateOk>
          <DateOk date="2015-08-21" />
        <DateOk date="2015-08-22" />
       <DateOk date="2015-08-23" />
        </ListDateOk>
      </Key>
    </ListKey>

    OutPut Instance:

    <Root>
    <Key IsValid="true" id="2">
    <DateOk date="2015-08-20"></DateOk>
    </Key>
    <Key IsValid="false" id="3">
    </Key>
    <Key IsValid="true" id="4">
    <DateOk date="2015-08-21"></DateOk>
    </Key>
    <Key IsValid="true" id="4">
    <DateOk date="2015-08-22"></DateOk>
    </Key>
    <Key IsValid="true" id="4">
    <DateOk date="2015-08-23"></DateOk>
    </Key>
    </Root>

    It will help you.



    Kind Regards, Anurag Prajesh (BizTalk Developer)


    Thursday, July 30, 2015 6:36 AM
  • Hi,

    The best option for you is to use create a schema as per your destination message and then you use the mapping to achieve  it . Custom dissembler component does not suits your requirement as nodes are not having sequence of repeatation     .

    Also option you have to create class object of the specified schema and then you can make a foreach loop to construct the required  message as xmldocument and then convert it to xlang message.

    Thanks

    Abhishek

    Friday, July 31, 2015 3:06 PM