Leave feedback
  • Question

    XPath in StoryTeller

Enter a new topic
  • Andrew Day Andrew Day
    0 likes 2192 views

    Hi, I am trying to access the data in a field in an XML file using a script attached to a repeater. I have tried the following different syntactic code:

    $PackingSlipIdNoLetters = stevalxpath("self::/Block_CustPackingSlipTrans[1]/CustPackingSlipTrans.m.A2X_WMSBillOfLading.hpePackingSlipIdNoLetters");

    Control Center tells me:

    0901 145509 (0507) 1 Libxml error message: 'Invalid expression, Invalid expression'.
    0901 145509 (0063) 1 Cannot evaluate xpath expression: 'self::/Block_CustPackingSlipTrans[1]/CustPackingSlipTrans.m.A2X_WMSBillOfLading.hpePackingSlipIdNoLetters'.

    $PackingSlipIdNoLetters = stevalxpath("/Block_CustPackingSlipTrans[1]/CustPackingSlipTrans.m.A2X_WMSBillOfLading.hpePackingSlipIdNoLetters");

    Control Center gives me no error message, but the variable is empty. The repeater is on CustPackingListJour which is the parent of Block_CustPackingSlipTrans child blocks and I want to access the first child block.

    Regards,

    Andrew Day

     

    Tuesday 01 September, 2015
  • Best Answer
    David Bares David Bares OpenText Employee Administrator StreamServe Employee
    0 likes

    What I see is wrong is a misunderstanding of what predicate [anything in square brackets] does.

    In reality it is a filter that you set on nodeset which you have selected so far.

    What your expression says in human readable interpretation is:

    In case that current is ...SlipJour get me all descendants for which the condition is true that position() = sum of child elements called ...WeightInKg

    Which to me seems like a non-sense, but I may be mistaking.

    You do not want a nodeset or a value, you want a sum. So the expression should start with sum(. Then you need to specify what should be selected for the sum and provide that as a parameter.

    And a side note, I do not like //, they are easy to type, but slow down the processing if used carelessly.

    Monday 14 September, 2015
  • David Bares David Bares OpenText Employee Administrator StreamServe Employee
    0 likes

    Script attached to repeater

    Script before repeater happens once before the nodes are selected. This is a great place to do the initialization before repeater.

    self::/Block_CustPackingSlipTran

    The first slash is what causes the syntax error. See how axes are used in XPath.

    If called from inside repeater, self::Block_CustPackingSlipTran would happen if current instance name is Block_CustPackingSlipTran

    stevalxpath("/Block_CustPackingSlipTrans[1]

    If you use standard strs message, absolute path starts with /data/message. Make sure you understand difference between relative and absolute XPath expressions. If using relative XPath, make sure your script is called on object within the repeater scope. In such case current repeater instance is a context node for evaluating XPath.

    http://www.w3.org/TR/xpath/

    Tuesday 01 September, 2015
  • Andrew Day Andrew Day
    0 likes

    Hi David,

    Thanks for your quick response. I have used your suggestion for relative XPath as follows:


    $PackingSlipIdNoLetters = stevalxpath("self::Block_CustPackingSlipJour/Block_CustPackingSlipTran s[position()=1]/CustPackingSlipTrans.m.A2X_WMSBillOfLading.hpePackingS lipIdNoLetters");

    This is on a Repeater for CustPackingSlipJour, of which there are 2 iterations. So my output has 2 lines in the log, with the first value of $PackingSlipIdNoLetters being spaces, and the second being "30005399", which is what I would expect to get from the field of the first CustPackingSlipJour/CustPackingSlipTrans[1]/CustPackingSlipTrans.m.A2X _WMSBillOfLading.hpePackingSlipIdNoLetters field. It is as if it is returning the values before reading the data.

    This is how my Story looks:

    It is as if the variable is picking up the value BEFORE the data has been read, not after. I must be misunderstanding how StreamServe gets it's data from XML using the Repeater.
    Any suggestions?

    Regards,

    Andrew Day

    Wednesday 02 September, 2015
  • David Bares David Bares OpenText Employee Administrator StreamServe Employee
    0 likes

    Do you have a sample XML (use StMsgSaveToFile to dump the message) and what do you want to achieve? Somebody can look at it.

    Looking at the dumped XML also helps validating the data as they very processed by the input event. It happens time to time that user expects something else than StoryTeller gets.

    Tiny focused SSD file would help too.

    Wednesday 02 September, 2015
  • Andrew Day Andrew Day
    0 likes

    Hi,
    You were right, the XML dump revealed that the data from the XML was not finding it's way into the Message. I recreated the Event from scratch and that fixed it: I can now see the data I expected to see. I have one remaining issue. I have to count the number of Pallets in the pallet block. The structure of the XML in XPath is:

    /data/message/Block_CustPackingSlipJour/Block_CustPackingSlipTrans/Bl ock_WMSPallet

    If I use MsgCountId(Block_WMSPallet) the returned value is the total number of those blocks. But I need the number of pallet block per CustPackingSlipJour. Is that possible using MsgCountId()?

    Regards,

    Andrew Day

    Thursday 03 September, 2015
  • David Bares David Bares OpenText Employee Administrator StreamServe Employee
    0 likes

    No, you cannot use MsgCountId(), but in StoryTeller you can use XPath.

    XPath expression: "count( Block_CustPackingSlipTrans/Block_WMSPallet )" will count all pallets in current context. You can use expression directly (subst, switch ) or call it from script (stEvalXPath ). In both cases make sure that you are inside /data/message/Block_CustPackingSlipJour repeater.

    Thursday 03 September, 2015
  • Andrew Day Andrew Day
    0 likes

    The good news is that adding the substitution with an XPath of "count( Block_CustPackingSlipTrans/Block_WMSPallet )" does work as you say. But I could not get the script "$palletCount = stevalxpath("count(Block_CustPackingSlip/Block_WMSPallet" to work. In CC I get the message "Cannot evaluate xpath expression ....".

    I really need to understand my failure to get this working in script as for another field I need to use the pallet id of the first WMSPallet record where the parent Block_CustPackingSlip/CustPackingSlipId = "A" in the repeater for CustPackingSlipJour.

    Regards,

    Andrew Day

    Thursday 03 September, 2015
  • David Bares David Bares OpenText Employee Administrator StreamServe Employee
    0 likes

    If something works in substitution, but now is script, then I suggest some syntax error in the script.

    From your text above it looks like you miss the closing parentesis of the count function.

    Thursday 03 September, 2015
  • Andrew Day Andrew Day
    0 likes

    Hi David,

    Again, you were correct - I didn't spot the missing closing parenthesis. So now it work fine. Thanks for all your help and quick responses.

    Regards,

    Andrew Day

    Thursday 03 September, 2015
  • Andrew Day Andrew Day
    0 likes

    Hi David,

    Sorry to be a pain but I am clearly missing something in my understanding of how to use StEvalXPath(). I thought I had it licked, but seems not.

    This code works fine in script on a repeater of CustPackingSlipJour:

    $PackingSlipIdNoLetters               = stevalxpath("self::Block_CustPackingSlipJour/Block_CustPackingSlipTran s[position()=1]/CustPackingSlipTrans.m.A2X_WMSBillOfLading.hpePackingS lipIdNoLetters");

    In a different document this code works fine (no repeater) in script:

    $custplant = stevalxpath("/data/message/WMSBillOfLading.custAccount");       

    But this code, although it evaluates OK, returns nothing:

    $custplant2 = stevalxpath("/data/message/Block_CustPackingSlipJour[position()=1]/Cus tPackingSlipJour.PackingSlipId");

    When I expect it to return “30SPS005399”.

    In my XML editor the XPath reads like so:

    /strsqueue/WMSBillOfLading[1]/Body[1]/WMSBillOfLading[1]/CustPackingS lipJour[1]/CustPackingSlipTrans[1]/CustPackingSlipTrans.PackingSlipId[ 1]

    And the data is this:

     

    I am attaching a copy of the XML input file and the XML dump from StMsgSaveToFile() and would appreciate your help.

    Regards,

    Andrew Day

    Monday 07 September, 2015

    Attached files

    BOL.zip 107 KB
  • David Bares David Bares OpenText Employee Administrator StreamServe Employee
    0 likes

    You are still fighting the problem in XMLIN.

    The BOL.XML file has 3 packing slip ids, the original XML file only two.

    StoryTeller does not know about the original XML, it only works with what you see in the dump file. And there the first PackingSlipId is empty

    The problem in input even usually comes with data field that is already present in current block. That closes current instance of block and creates new one.

    Monday 07 September, 2015
Next