Friday, December 16, 2011

A couple minor XML parsing tricks with SOA/OSB

Mostly for my own memory before I forget them, don't want to re-learn these little things every 6 months.

1. sometimes you just need to ship a full XML payload to somewhere, but at the shipping point (where you need to hand it off) you don't really care about the actual structure (schema). For example, publishing various messages to a queue. You can define a simple input schema that takes a string.

...<element name="in" type="string"/>...

In BPEL editor, when you need to transform some source variable (say "src") with a structured schema, e.g.
<src>
  <foo>..
    <bar>...</bar>
     <car>...</car>
</foo>
</src>
your initial XSLT edit comes up that you can only drag one value from the "src" to the target "in" element.

Well, go ahead map that. Then open XSLT in source view, just type in your entire mapping like:

<in>
   <src>
    <foo>
      <bar> map bar's value</bar>
     <car> car's value</car>
    </foo>
  </src>
</in>

now you can map a full complex XML payload under "in". The only drawback is that you can't use the map editor to do this (it won't even open), because it doesn't know what to do with it (you are stuffing an entire XML structure inside one string element).

This is almost like an assignment operation in a "typeless" programing language.

2. Along the same line, you can stick an array of element into "in". That's what I actually did. But initially, I created a real "array" type, like:
<element name="srcList">
....
    <element name="srcElems" type="src" maxOccurs="unbounded"/>
...
</element>
I first mapped the incoming payload (from another structure) into this, then I assign (append) the resulting array into "in". It's unnecessary. Just go ahead stick the mapping from the source into an array of "src" direct into "in". Saves the trouble of creating an intermediate type.

3. Finally, when I get my "in" variable sent into OSB (with varies XML elements), I have a requirement to strip off all namespaces (change namespace is the same thing).
If I do assignment like this:
    $body/jms2:Publish/in/*
the result variable will retain all the namespaces from whatever contained in that "*". It may look something like:
<src xmlns:a="a.com" xmlns="blah.com" xmlns:b="bar.com">
  <foo xmlns="">...</foo> </src>
It may even come out more weird than this anyway.

The cheap way (without doing full fledge XSLT with schemas) is like:
<src>
  <foo>
    <bar>{$body/jms2:Publish/in/evt:foo/evt:bar/text()}</bar>
     <car>{$body/jms2:Publish/in/evt:foo/evt:car/text()}</car>
  </foo>
</src>

4. for next one, i should do a java callout, it has been a while, i should document the detailed steps