Please help me on mapping this xml

Home Page Forums BizTalk 2004 – BizTalk 2010 Please help me on mapping this xml

Viewing 1 reply thread
  • Author
    Posts
    • #13664

      I have an input xml like this:

      <ItemDetails xmlns=\”\”>
      <Orders>
      <ID>Order01</ID>
      <Branch1>
      <Type01>
      <Name>Name1</Name>
      </Type01>
      </Branch1>
      </Orders>
      <Orders>
      <ID>Order01</ID>
      <Branch1>
      <Type02>
      <ItemCode>Item01</ItemCode>
      </Type02>
      </Branch1>
      </Orders>
      <Orders>
      <ID>Order01</ID>
      <Branch1>
      <Type03>
      <CDate>20060517</CDate>
      </Type03>
      </Branch1>
      </Orders>
      <Orders>
      <ID>Order02</ID>
      <Branch1>
      <Type01>
      <Name>Name2</Name>
      </Type01>
      </Branch1>
      </Orders>
      <Orders>
      <ID>Order02</ID>
      <Branch1>
      <Type02>
      <ItemCode>Item02</ItemCode>
      </Type02>
      </Branch1>
      </Orders>
      <Orders>
      <ID>Order02</ID>
      <Branch1>
      <Type03>
      <CDate>20060518</CDate>
      </Type03>
      </Branch1>
      </Orders>
      </ItemDetails>

      I want to output:

      Name1,Item01,20060517
      Name2,Item02,20060518

      one output for each orderID, but how can I combine them together?

      anybody suggestions?

    • #13665

      Thanks~

      Guess I need to set the for-each loop to \”Orders\” since I want the OrderID, but got error, so I went back to your way, still got error, maybe I set something wrong for getting the OrderID value, could you give little bit more details?

      • #13666

        It helps.
        Thanks a lot!

        • #13667

          those code above……so did you guys use them in XSLT inline call template script? I test this sample but it doen’t work for me 🙁

          • #13668

            This map relies on the the Orders nodes being in the right sequence and hard codes Branch1.

            [code:1:ffdd0bfa8f]<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\">
            <xsl:output omit-xml-declaration=\"yes\" version=\"1.0\" method=\"xml\" indent=\"yes\" />
            <xsl:key name=\"orderkey\" match=\"/ItemDetails/Orders\" use=\"ID\"/>
            <xsl:template match=\"/\">
            <xsl:apply-templates select=\"/ItemDetails\" />
            </xsl:template>
            <xsl:template match=\"/ItemDetails\">
            <root>
            <xsl:for-each select=\"Orders\">
            <xsl:variable name=\"group\" select=\"key(’orderkey’, ID)\"/>
            <xsl:if test=\"generate-id($group[1]) = generate-id()\">
            <Record>
            <xsl:for-each select=\"$group\">
            <xsl:if test=\"Branch1/Type01\">
            <xsl:element name=\"Name\">
            <xsl:value-of select=\"Branch1/Type01/Name\" />
            </xsl:element>
            </xsl:if>
            <xsl:if test=\"Branch1/Type02\">
            <xsl:element name=\"ItemCode\">
            <xsl:value-of select=\"Branch1/Type02/ItemCode\" />
            </xsl:element>
            </xsl:if>
            <xsl:if test=\"Branch1/Type03\">
            <xsl:element name=\"CDate\">
            <xsl:value-of select=\"Branch1/Type03/CDate\" />
            </xsl:element>
            </xsl:if>
            </xsl:for-each>
            </Record>
            </xsl:if>
            </xsl:for-each>
            </root>
            </xsl:template>
            </xsl:stylesheet> [/code:1:ffdd0bfa8f]

            • #13669

              I have switched to doing complex maps like this all in XSLT (and using Stylus Studio to debug).

              Following is one way to do it that comes to mind – there may be better alternatives – if someone knows one – please reply also!

              Here’s an idea of how to do it in native XSLT – do a for-each loop on something like:

              /ItemDetails/Orders[Branch1/Type01/Name]
              i.e. select all Orders that have a child called \”Branch\”.

              Then build a variable that will contain another XPATH to lookup the other values – your goal will be to build a variable that equals something like this:

              /ItemDetails/Orders[ID=’Order01′]/Branch1/Type02/ItemCode

              The trick is you have to contatenate in the value ‘Order01’ from the order you current have in your for-next loop.

              Then you use this Xpath/Variable to build a select statement and copy over the item, then repeat the same type of logic for the \”type\”.

              Another idea – I have a complex map I’ve been working on – and I have seriously been thinking about not using a map at all, but using a C# static helper class/method. If you know C# and XML classes well, this might be a valid alternative.

              I suppose you’ll also have to create a CSV flat file schema.

              Neal Walters
              http://Biztalk-Training.com – Learn Biztalk Faster
              http://Sharepoint-Training.com – End User Training

              • #13670

                This Xpath will give you the two orders that have a \”name\” subelement:
                /ItemDetails/Orders[Branch1/Type01/Name] so this should be the basis for your for-next loop.

                So here is the first pass to test:
                <xsl:stylesheet version=\”1.0\” xmlns:xsl=\”http://www.w3.org/1999/XSL/Transform\”>

                <xsl:template match=\”/\”>
                <OutputOrders>

                <xsl:for-each select=\”/ItemDetails/Orders[Branch1/Type01/Name]\”>
                <Order>
                <Name>
                <xsl:value-of select=\”Branch1/Type01/Name\”/>
                </Name>
                </Order>
                </xsl:for-each>
                </OutputOrders>
                </xsl:template>
                </xsl:stylesheet>

                Now the trick is to lookup the other fields in the loop using XPath.
                So your goal is to build an Xpath that looks like this:

                //ItemDetails/Orders[ID=’Order01′]/Branch1/Type02/ItemCode

                This will give you the ItemCode for Order01.

                Here’s what I got so far:

                <?xml version=\”1.0\”?>
                <xsl:stylesheet version=\”1.0\” xmlns:xsl=\”http://www.w3.org/1999/XSL/Transform\”>

                <xsl:template match=\”/\”>
                <OutputOrders>

                <xsl:for-each select=\”/ItemDetails/Orders[Branch1/Type01/Name]\”>
                <Order>
                <Name>
                <xsl:value-of select=\”Branch1/Type01/Name\”/>
                </Name>
                <xsl:variable name=\”myXpathItemCode\”>//ItemDetails/Orders[Branch/Type01/Name=’\”<xsl:value-of select=\”ID\”/>’]Branch1/Type02/ItemCode]</xsl:variable>
                <debugXpath>
                <xsl:value-of select=\”$myXpathItemCode\”/>
                </debugXpath>
                <ItemCode>
                <xsl:value-of select=\”$myXpathItemCode\”/>
                </ItemCode>
                </Order>
                </xsl:for-each>
                </OutputOrders>
                </xsl:template>
                </xsl:stylesheet>

                But I’m having trouble figuring out to get the variable to substitute the actual Xpath.

                I have posted a question to Stylus Studio – they are experts in XSLT:
                http://www.stylusstudio.com/SSDN/default.asp?fid=48

                • #13671

                  [code:1:c20522979f]<?xml version=\"1.0\"?>
                  <xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">

                  <xsl:template match=\"/\">
                  <OutputOrders>

                  <xsl:for-each select=\"/ItemDetails/Orders[Branch1/Type01/Name]\">
                  <Order>
                  <xsl:variable name=\"ID\">
                  <xsl:value-of select=\"ID\"/>
                  </xsl:variable>
                  <ID>
                  <xsl:value-of select=\"$ID\"/>
                  </ID>
                  <Name>
                  <xsl:value-of select=\"Branch1/Type01/Name\"/>
                  </Name>
                  <xsl:variable name=\"myXpathItemCode\">//ItemDetails/Orders[ID='<xsl:value-of select=\"ID\"/>’]/Branch1/Type02/ItemCode</xsl:variable>
                  <DebugXpath>
                  <xsl:value-of select=\"$myXpathItemCode\"/>
                  </DebugXpath>

                  <xsl:variable name=\"myXpathItemValue\" select=\"//ItemDetails/Orders[ID=$ID]/Branch1/Type02/ItemCode\"/>

                  <ItemCode>
                  <xsl:value-of select=\"$myXpathItemValue\"/>
                  </ItemCode>
                  </Order>
                  </xsl:for-each>
                  </OutputOrders>
                  </xsl:template>
                  </xsl:stylesheet>[/code:1:c20522979f]

                  Here’s another example. One of my issues in debugging was that I had [ID=’$ID’] [ID=$ID].

                  The difference between my code and Greg’s is that this one does not require the nodes to be in specific sequence.

                  • #13672

                    I have come to \”HATE\” the inline XSLT script functoid. The fact they only give you about 12 lines and don’t allow you to resize the window is HORRIBLE.

                    If I have a lot of XSLT, I go with an entire XSLT replacement. Just click on the grid and set the property \”Custom XSLT Path\” to the name of the .XSLT stylehseet. But XSLT is kind of an ugly language also, a necessary evil in many cases.

                    This allows me to test the XSLT with a tool such as Stylus Studio which has a full interactive XSLT debugger. See my blog: http://nealwalters.blogspot.com (May post).

                    • #13673

                      By the way, once you specify the \”Custom XSLT path\” the entire Biztalk grid is ignored, even if there are still icons on it. I usually delete all the icons/functoids to remind myself that it’s an external XSLT map. This could be very confusing for another developer who opens the map, sees the functoids, and doesn’t notice the \”Custom XSLT Path’

Viewing 1 reply thread
  • The forum ‘BizTalk 2004 – BizTalk 2010’ is closed to new topics and replies.