Home Page › Forums › BizTalk 2004 – BizTalk 2010 › Please help me on mapping this xml
- This topic has 9 replies, 1 voice, and was last updated 6 years, 10 months ago by
community-content.
-
AuthorPosts
-
-
May 22, 2006 at 4:09 PM #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,20060518one output for each orderID, but how can I combine them together?
anybody suggestions?
-
May 22, 2006 at 9:47 PM #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?
-
May 25, 2006 at 7:52 PM #13666
It helps.
Thanks a lot!-
May 26, 2006 at 2:14 PM #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 🙁
-
May 24, 2006 at 12:25 PM #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]-
May 22, 2006 at 5:12 PM #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-
May 23, 2006 at 11:15 PM #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-
May 25, 2006 at 5:41 PM #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.
-
May 26, 2006 at 2:25 PM #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).
-
May 26, 2006 at 2:28 PM #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’
-
-
-
-
-
-
-
-
-
-
AuthorPosts
- The forum ‘BizTalk 2004 – BizTalk 2010’ is closed to new topics and replies.