|
Home > Archive > BizTalk Server General > April 2006 > BizTalk Map Inline XSLT splitter
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
BizTalk Map Inline XSLT splitter
|
|
|
| Hello,
I have the following problem.
I have an xml message that contains many POs that needs to be split
into separate messages.
The inbound message looks like this:
<POs>
<POLine>
<PONumber>123</PONumber>
<POLineNumber>1</POLineNumber>
<Quantity>12</Quantity>
</POLine>
<POLine>
<PONumber>123</PONumber>
<POLineNumber>2</POLineNumber>
<Quantity>23</Quantity>
</POLine>
<POLine>
<PONumber>456</PONumber>
<POLineNumber>2</POLineNumber>
<Quantity>23</Quantity>
</POLine>
</POs>
The outbound messages should look like:
<PO>
<PONumber>123</PONumber>
<POLines>
<POLineNumber>1</POLineNumber>
<Quantity>12</Quantity>
</POLines>
<POLines>
<POLineNumber>2</POLineNumber>
<Quantity>23</Quantity>
</POLines>
</PO>
So far, what I'm getting is that the simplest way to do this is to use
Inline XSLT in a scripting functoid in a map.
I don't know XSLT.
What I'm getting from doing research is something about using <xsl:key>
and <xsl:for-each-group>
Besides not knowing exactly what such a script should look like, I'm
also pretty confused about where this scripting functoid is actually
supposed to link in the BizTalk map, or what it actually outputs.
Can anyone help clear this up? A very simple example would be
appreciated because I get lost in the more complex examples.
Ana
| |
| Eric Stott 2006-04-10, 7:33 pm |
| I have created an example to do just that:
http://www.stottcreations.com/blog/?p=33
Eric
"AnaB" <anabanana.discussions@yahoo.com> wrote in message
news:1144178958.471150.164490@u72g2000cwu.googlegroups.com...
> Hello,
> I have the following problem.
> I have an xml message that contains many POs that needs to be split
> into separate messages.
>
> The inbound message looks like this:
> <POs>
> <POLine>
> <PONumber>123</PONumber>
> <POLineNumber>1</POLineNumber>
> <Quantity>12</Quantity>
> </POLine>
> <POLine>
> <PONumber>123</PONumber>
> <POLineNumber>2</POLineNumber>
> <Quantity>23</Quantity>
> </POLine>
> <POLine>
> <PONumber>456</PONumber>
> <POLineNumber>2</POLineNumber>
> <Quantity>23</Quantity>
> </POLine>
> </POs>
>
> The outbound messages should look like:
> <PO>
> <PONumber>123</PONumber>
> <POLines>
> <POLineNumber>1</POLineNumber>
> <Quantity>12</Quantity>
> </POLines>
> <POLines>
> <POLineNumber>2</POLineNumber>
> <Quantity>23</Quantity>
> </POLines>
> </PO>
>
>
> So far, what I'm getting is that the simplest way to do this is to use
> Inline XSLT in a scripting functoid in a map.
> I don't know XSLT.
> What I'm getting from doing research is something about using <xsl:key>
> and <xsl:for-each-group>
>
> Besides not knowing exactly what such a script should look like, I'm
> also pretty confused about where this scripting functoid is actually
> supposed to link in the BizTalk map, or what it actually outputs.
>
> Can anyone help clear this up? A very simple example would be
> appreciated because I get lost in the more complex examples.
>
> Ana
>
| |
| Greg Forsythe 2006-04-10, 7:33 pm |
| I am not sure if you can use an inline XSLT functoid
The approach I have used is a custom XSLT file
You create a file "mapname.xslt" and add it to your project
Create a map and select the input and output schemas.
Click on the map grid and set the Custom XSLT property to your XSLT file -
"mapname.xslt".
Your custom XSLT file should look something like this:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl s0" version="1.0"
xmlns:s0="urn:your:input:Namespace"
xmlns:ns0="urn:your:output:Namespace">
<xsl:output omit-xml-declaration="yes" version="1.0" method="xml" />
<xsl:key name="POkey" match="/s0:POs/POLine" use="PONumber"/>
<xsl:template match="/">
<xsl:apply-templates select="/s0:POs" />
</xsl:template>
<xsl:template match="/s0:POs">
<ns0:POs>
<xsl:for-each select="POLine">
<xsl:variable name="group" select="key('POkey', PONumber)"/>
<xsl:if test="generate-id($group[1]) = generate-id()">
<PO>
<PONumber>
<xsl:value-of select="PONumber" />
</PONumber>
<xsl:for-each select="$group">
<POLines>
<POLineNumber>
<xsl:value-of select="POLineNumber" />
</POLineNumber>
<Quantity>
<xsl:value-of select="Quantity" />
</Quantity>
</POLines>
</xsl:for-each>
</PO>
</xsl:if>
</xsl:for-each>
</ns0:POs>
</xsl:template>
</xsl:stylesheet>
You will need to edit XSLT to set correct namespaces and add the rest of
the fields
Greg
"AnaB" <anabanana.discussions@yahoo.com> wrote in message
news:1144178958.471150.164490@u72g2000cwu.googlegroups.com...
> Hello,
> I have the following problem.
> I have an xml message that contains many POs that needs to be split
> into separate messages.
>
> The inbound message looks like this:
> <POs>
> <POLine>
> <PONumber>123</PONumber>
> <POLineNumber>1</POLineNumber>
> <Quantity>12</Quantity>
> </POLine>
> <POLine>
> <PONumber>123</PONumber>
> <POLineNumber>2</POLineNumber>
> <Quantity>23</Quantity>
> </POLine>
> <POLine>
> <PONumber>456</PONumber>
> <POLineNumber>2</POLineNumber>
> <Quantity>23</Quantity>
> </POLine>
> </POs>
>
> The outbound messages should look like:
> <PO>
> <PONumber>123</PONumber>
> <POLines>
> <POLineNumber>1</POLineNumber>
> <Quantity>12</Quantity>
> </POLines>
> <POLines>
> <POLineNumber>2</POLineNumber>
> <Quantity>23</Quantity>
> </POLines>
> </PO>
>
>
> So far, what I'm getting is that the simplest way to do this is to use
> Inline XSLT in a scripting functoid in a map.
> I don't know XSLT.
> What I'm getting from doing research is something about using <xsl:key>
> and <xsl:for-each-group>
>
> Besides not knowing exactly what such a script should look like, I'm
> also pretty confused about where this scripting functoid is actually
> supposed to link in the BizTalk map, or what it actually outputs.
>
> Can anyone help clear this up? A very simple example would be
> appreciated because I get lost in the more complex examples.
>
> Ana
>
| |
|
| Hello, Greg,
I used the xsl and it works great. That is, I can output my messages at
either 1:
<POs>
<PO>
<POLine>
<POLineNo />
<Qty />
<POLine>
<POLine>
<POLineNo />
<Qty />
<POLine>
</PO>
<PO>
<POLine>
<POLineNo />
<Qty />
<POLine>
<POLine>
<POLineNo />
<Qty />
<POLine>
</PO>
</POs>
or 2 (obviously not a valid xml document):
<PO>
<POLine>
<POLineNo />
<Qty />
<POLine>
<POLine>
<POLineNo />
<Qty />
<POLine>
</PO>
<PO>
<POLine>
<POLineNo />
<Qty />
<POLine>
<POLine>
<POLineNo />
<Qty />
<POLine>
</PO>
How do I get the POs from the second part of this to be output as
separate messages?
Ideas?
Thanks again for your help :D
| |
| Greg Forsythe 2006-04-10, 7:34 pm |
| The problem here is XSLT 1.0 will only output 1 message, so you will have to
map first and then debatch the message.
This can be done a number of ways, either in a pipeline or an orchestration.
I assume your map will be on the receive port and the completed message will
be published to the messagebox.
1. Pipeline Debatch
You can have a send port that basically functions as a loopback.
e.g. the send port writes to a file where another receive location picks up
the file and debatches the message.
2. Orchestration Debatch
The complete message is processed by an orchestration which loops through
the complete message and sends individual PO messages, you can use direct
binding on this send port and process the individual POs in another
orchestration.
For more details on debatching, Stephen Thomas has written extensively on
this topic:
http://www.biztalkgurus.com/Samples...g-Grouping.html in this example he
uses two maps to sort and group rather than the one map scenario you are
using.
And
http://www.biztalkgurus.com/WhitePa...izTalk2004.html
Greg
"AnaB" <anabanana.discussions@yahoo.com> wrote in message
news:1144255283.156133.92840@u72g2000cwu.googlegroups.com...
> Hello, Greg,
> I used the xsl and it works great. That is, I can output my messages at
> either 1:
> <POs>
> <PO>
> <POLine>
> <POLineNo />
> <Qty />
> <POLine>
> <POLine>
> <POLineNo />
> <Qty />
> <POLine>
> </PO>
> <PO>
> <POLine>
> <POLineNo />
> <Qty />
> <POLine>
> <POLine>
> <POLineNo />
> <Qty />
> <POLine>
> </PO>
> </POs>
>
> or 2 (obviously not a valid xml document):
> <PO>
> <POLine>
> <POLineNo />
> <Qty />
> <POLine>
> <POLine>
> <POLineNo />
> <Qty />
> <POLine>
> </PO>
> <PO>
> <POLine>
> <POLineNo />
> <Qty />
> <POLine>
> <POLine>
> <POLineNo />
> <Qty />
> <POLine>
> </PO>
>
> How do I get the POs from the second part of this to be output as
> separate messages?
> Ideas?
> Thanks again for your help :D
>
| |
|
| Hello, Greg,
What I was trying to get to work was to have an XML file mapped from
lets say schemaIn(original) to schemaGrouped (after XSLT conversion)
then send it through a pipeline to debatch it with a schemaEnvelope and
schemaDocument schemas.
But, the problem that I ran into was that schemaGrouped and
schemaEnvelope have different namespaces, so I couldn't process the
message.
So I get an error to the effect of "Document type
http://mySchemas.schemaGrouped#POs does not match any of the given
schemas".
I'm now trying to figure out how to get that to work.
I'll be looking at the links above and more.
Thank for all your help.
Ana
| |
|
| I've figured out that I need to set the Schema Target Namespace on my
schemaGrouped and schemaEnvelope to be the same. Ok, done.
Now what are all the rules to avoid "multiple schemas match the message
type error"?
Supposed I have schemas, pipelines and orchestrations. How are these
supposed to be grouped/separated into projects?
If 1: I have schemaGrouped and schemaEnvelope schemas set with the same
Schema Target Namespace
If 2: I have pipelines that user both of these schemas
If 3: I have orchestrations that use both of these schemas
I've figure out that the two schemas need to go into separate projects.
Ok, what about the two pipelines that reference them? Another two
projects? What about Orchestrations that reference them separate
projects again?
I'm used to grouping all my schemas together, pipelines together,
orchestrations together/separate...What's the trick here?
Thanks a lot.
Ana :D
| |
| Greg Forsythe 2006-04-10, 7:34 pm |
| You should not deploy two schema with the same namespace and root node into
Biztalk.
Putting the schema into different projects does not help as they end up in
the same database when they are deployed.
The answer to your problem is to remove the schemaGrouped, you do not need
it.
Because you are using a custom XSLT, you can use the schemaEnvelope as the
output of the map.
The Biztalk runtime does not validate the output of the map, you have to
explicity use the XmlValidate pipeline component
When using Test Map you can set the Validate Output property to false.
If you wish to validate the map output, the you can create a single schema
file with both envelope and document.
So both envelope and document are root nodes in the same schema
<schema>
Envelope
Document (maxOccurs=unbounded ref=Document)
Document
Fields
Creating this schema can be quite tricky, if you would like assistance,
email me you schema files
Greg
"AnaB" <anabanana.discussions@yahoo.com> wrote in message
news:1144333750.883326.288460@z34g2000cwc.googlegroups.com...
> I've figured out that I need to set the Schema Target Namespace on my
> schemaGrouped and schemaEnvelope to be the same. Ok, done.
> Now what are all the rules to avoid "multiple schemas match the message
> type error"?
> Supposed I have schemas, pipelines and orchestrations. How are these
> supposed to be grouped/separated into projects?
>
> If 1: I have schemaGrouped and schemaEnvelope schemas set with the same
> Schema Target Namespace
> If 2: I have pipelines that user both of these schemas
> If 3: I have orchestrations that use both of these schemas
>
> I've figure out that the two schemas need to go into separate projects.
> Ok, what about the two pipelines that reference them? Another two
> projects? What about Orchestrations that reference them separate
> projects again?
>
> I'm used to grouping all my schemas together, pipelines together,
> orchestrations together/separate...What's the trick here?
> Thanks a lot.
>
> Ana :D
>
|
|
|
|
|