Showing posts with label XPath. Show all posts
Showing posts with label XPath. Show all posts

Saturday, September 02, 2017

SOA 12c JavaScript: Shaken, not stirred

Have you ever faced XML/XPath limitations? I bet you have. Mostly it's related to the string manipulations. Parsing, complex replacements, regular expressions, array transformations, I don't even start about math or anything else, that every modern language has out of the box. In the Oracle SOA world, you are moaning and pull Java Embedded Activity to the process, every time when you need something like that.

Sure you could use Java string operations in XSLT but it means you should create XSLT document for that matter. SOA 12c is a game changer. With the native JSON support, it brings you JavaScript.
The question "Can I use JavaScript with my XML data?" has the answer: " Yes, You can!".

Sunday, August 27, 2017

XPath. One with the clingy attributes


Hi there. Winter is coming, just not today. Because today it's raining cats, dogs and gators; High Florida season is on his way and I have time for the another little trinket. It's based on the same data types we have played around with apples and oranges. It's not exactly related. but I've reused XML Schema to show you a little side effect of the XPath selector. You have run into that if you use strict type validation for each and every activity in your process, but I bet you don't. It's pretty normal to validate data on the edges, in the BPEL case - check the service input and make sure that you produce the response, that composite's clients expect to have.

 This minimalistic composite has only a few steps, but can simulate behavior we need:

  • Check Incoming XML document (using partner link property)
  • Perform XPath query by attribute value
  • Validate output  variable
  • Return response
The one truly interesting activity here is the assign SetResponse. Let's take a look into source code:
<assign name="SetResponse">
<copy>
 <from>
  <literal>
   <GroceryList xmlns="http://mmikhail.com/sample/xml/Orchard">
    <Item Name="Apples" Type="bushel">1</Item>
    <Item NMame="Pears" Type="pound">4</Item>
   </GroceryList>
  </literal>
 </from>
 <to expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">$VariableWitthAttributes</to>
</copy>
<copy>
 <from>$VariableWitthAttributes/ns2:Item[@Name="Apples"]</from>
 <to expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">$outputVariable.payload/client:response</to>
</copy>
</assign>

Activity populates variable with the array of the element Item. You can select Item from the list either by index or by attribute name. That's exactly what the second copy does.  It selects Item value with the attribute Name equal to "Apples". Nothing fancy so far, good old XPath expressions and assignments. The CheckOutput activity validates output message against XML Schema.  It's a string and we do not expect any traps here. Le'ts compile, deploy and test the process.

Ouch, validation failed with the error message:

<bpelFault>
 <faultType>0</faultType>
 <invalidVariables xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable">
  <part name="summary">
   <summary>Failed to validate bpel variable.
Validation of variable outputVariable failed.
The reason was: Attribute 'Name' not expected.
Please handle the exception in bpel.</summary>
  </part>
 </invalidVariables>
</bpelFault>

And if you check the assign activity you'll see that all element attributes have traversed to the target variable. I bet it's not exactly what you have expected to see, but you do and it's the same for 12c and 11g. The solution is quite simple, just slightly modify selector for instance:

 <from>string($VariableWitthAttributes/ns2:Item[@Name="Apples"])</from>

Now composite works exactly as expected.

It looks like nothing, but think about it:
You have selected something by one attribute, but in fact, you have exposed not only this one but all of them and they may contain some sensitive information, like dates, user names, entity IDs and so on.
Hope it will help you to build more reliable and secure applications. Good luck with that.



Friday, December 30, 2011

XPath - Terra Ignota


There are more things in heaven and earth, Horatio,
Than are dreamt of in your philosophy.

As usual before  holidays we've got another issue with timeouts,  adapters errors and database performance.
I found that DB Adapter used several queries and then joins result sets. This way get us right result (very simplified version you can see  bellow) with pretty far from optimal performance. 
<off:OfferActionCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                           xmlns:off="http://xmlns.oracle.com/offer">
  <off:OfferAction>
    <off:id>2121</off:id>
    <off:offerPositionId>
      <off:id>2133</off:id>
      <off:positionNum>3</off:positionNum>
    </off:offerPositionId>
    <off:offerActionDetalCollection>
      <off:OfferActionDetal>
        <off:id>2262</off:id>
      </off:OfferActionDetal>
      <off:OfferActionDetal>
        <off:id>2263</off:id>
      </off:OfferActionDetal>
    </off:offerActionDetalCollection>
  </off:OfferAction>
</off:OfferActionCollection>
Option  'Use Outer Join ..' corrects  query issues , but returns non-unique collection. Like this one:
<off:OfferActionCollection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                           xmlns:off="http://xmlns.oracle.com/offer">
  <off:OfferAction>
    <off:id>2121</off:id>
    <off:offerPositionId>
      <off:id>2133</off:id>
      <off:positionNum>3</off:positionNum>
    </off:offerPositionId>
    <off:offerActionDetalCollection>
      <off:OfferActionDetal>
        <off:id>2262</off:id>
      </off:OfferActionDetal>
      <off:OfferActionDetal>
        <off:id>2263</off:id>
      </off:OfferActionDetal>
    </off:offerActionDetalCollection>
  </off:OfferAction>
  <off:OfferAction>
    <off:id>2121</off:id>
    <off:offerPositionId>
      <off:id>2133</off:id>
      <off:positionNum>3</off:positionNum>
    </off:offerPositionId>
    <off:offerActionDetalCollection>
      <off:OfferActionDetal>
        <off:id>2262</off:id>
      </off:OfferActionDetal>
      <off:OfferActionDetal>
        <off:id>2263</off:id>
      </off:OfferActionDetal>
    </off:offerActionDetalCollection>
  </off:OfferAction>
</off:OfferActionCollection>

I realised that I don't know much about DB Adapter, so we decide to create XQuery/XPath (or anything else)  to filer collection. 
Well, in fact now I realise that I know about X* almost nothing. By the way, after several hours googling, writing and trying  I found an acceptable message transformation expression.

It loops thru distinct values of OfferAction/id (for clause) and returns first node of Xpath result ( /OfferAction[off:id=$ActionId][1]).
The hardest thing for me was - how to combine XPath filters and expressions.

It works just perfect, but I think that next time I'll play on my own field - 
 queries, indexes and hints.

Happy New Year to everyone! Hope to see you in the next year.