Topic
  • 5 replies
  • Latest Post - ‏2019-08-15T17:36:31Z by swlinn
rohit_dp
rohit_dp
19 Posts

Pinned topic DataPower - Gateway script to read all subchild elements from the child element if matches the condition

‏2019-07-26T16:07:27Z | datapower gateway readasxml

Hi,

 

How can we get all subchild elements value if one of the subchild element value meets the condition ?

 

I have found some useful info in "https://www.ibm.com/developerworks/community/forums/html/topic?id=2a3e0efa-7042-4729-8ddf-0cbd13effcf0". But i want something more than the solution suggested in the link.

 

So let me take the same example.. 

 

<access>
    <id>
        <username>joe</username>
        <pw>password1</pw>
        <OutputCredential>group1</OutputCredential>
    </id>
    <id>
        <username>jane</username>
        <pw>password2</pw>
        <OutputCredential>group2</OutputCredential>
    </id>
</access>

 

Now, lets say if by some logic if we get value "joe" as an output variable then we want to get value of all it's subchild elements... like password1, group1, etc.

 

If you look at the link, Hermann has suggested one solution (which i think i can use it as we are using DP 7.6).. below is the excerpt of the thread..

var fs = require ('fs');
var transform = require('transform');

var user = "joe";

fs.readAsXML("local:///access.xml", function(error,xml) {
   if (error) {
     // Handle the error.
   } else {
     var options = { 
       'expression': "string(/access/id/pw[../username='"+user+"'])",
       'xmldom': xml
     };
              
     transform.xpath(options, function(err, xmlNodeList) {
       if (err) {
         session.out.write(err);
       } else {
         session.output.write(xmlNodeList);
       }
     });
   }
});

 

I tried that and it did work for me .. but with this i'm getting only one subchild element value.

 

I tried to extend this solution but no luck.. below is what i tried with which I'm getting empty value for "OutputCredential"..

fs.readAsXML("local:///extended/XML/smaple.xml", function(error, xml) {
    if (error) {
        console.info("Could not find the XML file.");
    } else {
        var options1 = {
            'expression': "string(/access/id/pw[../username='"+user+"'])",
            'xmldom': xml
        };
        var options2 = {
            'expression': "string(/access/id/pw/OutputCredential[../username='"+user+"'])",
            'xmldom': xml
        };
        
        transform.xpath(options1, function(err, xmlNodeList1) {
       if (err) {
         session.out.write(err);
       } else {
          transform.xpath(options2, function(err, xmlNodeList2) {
              if (err) {
                  session.out.write(err);
              } else {
                  console.info("XMLNodeList1: " + xmlNodeList1);
                  console.info("XMLNodeList2: " + xmlNodeList2);
              }
          });
       }
        });
    }
});

Please advise.

 

Thanks,

Rohit

  • HermannSW
    HermannSW
    8677 Posts

    Re: DataPower - Gateway script to read all subchild elements from the child element if matches the condition

    ‏2019-07-27T23:36:23Z  

    Please try this alternate XPath expression in your first code sample:

    "/access/id/*[../username='"+user+"']"
    

    That returns all the nodes.

    You do not want to apply string() to nodelist since by XPath 1.0 spec that does return string value of 1st node only:
    http://dev.cs.ovgu.de/html+xml+xslt/xpath-spec-1.0/REC-xpath-19991116.html#section-String-Functions

    Hermann.

    Updated on 2019-07-27T23:42:33Z at 2019-07-27T23:42:33Z by HermannSW
  • rohit_dp
    rohit_dp
    19 Posts

    Re: DataPower - Gateway script to read all subchild elements from the child element if matches the condition

    ‏2019-07-29T22:03:37Z  
    • HermannSW
    • ‏2019-07-27T23:36:23Z

    Please try this alternate XPath expression in your first code sample:

    <pre class="javascript dw" dir="ltr">"/access/id/*[../username='"+user+"']" </pre>

    That returns all the nodes.

    You do not want to apply string() to nodelist since by XPath 1.0 spec that does return string value of 1st node only:
    http://dev.cs.ovgu.de/html+xml+xslt/xpath-spec-1.0/REC-xpath-19991116.html#section-String-Functions

    Hermann.

    Thanks, Hermann.

     

    It did work.. I used the suggested XPath expression along with nodelist item(x).textContent to get the required element value.

     

    Now, I'm facing another issue... i'm not able to capture the error that may occur if the "username" is not present in the example XML file..

    You have answered the question I asked in the topic.. so if required I'm happy to submit below question in new topic.

     

    To give you the background -

    Actually I'm trying to customize the error code and description sent to the client by DP. So I have created a XML file where I have defined DP generated error-code/sub-code, the customized error-code, and error description.

    So whenever the call fails at DP.. let's there is a JSON schema validation error.. the gateway script configured in error rule looks into the XML file and send the customized error-code and error description to the client.

    <?xml version="1.0"?>
    <codes>
     <errorCode>
      <dpCode>0x00230001-0x01d30003</dpCode>
      <usccCode>ERROR03</usccCode>
      <description>JSON Schema Validation Error.</description>
     </errorCode>
     <errorCode>
      <dpCode>0x01130006-0x00000000</dpCode>
      <usccCode>ERROR04</usccCode>
      <description>Failed to establish backside connection.</description>
     </errorCode>
    </codes>

     

    Now, in case, the DP generated error code is missing/not-defined in XML file then client does not get anything.. it gets empty JSON response. So for such scenarios I want to send generic customized code to client which will make me aware as well to re-verify the XML.

     

    Please advise.

     

    Thanks,

    Rohit

  • HermannSW
    HermannSW
    8677 Posts

    Re: DataPower - Gateway script to read all subchild elements from the child element if matches the condition

    ‏2019-07-31T07:52:41Z  
    • rohit_dp
    • ‏2019-07-29T22:03:37Z

    Thanks, Hermann.

     

    It did work.. I used the suggested XPath expression along with nodelist item(x).textContent to get the required element value.

     

    Now, I'm facing another issue... i'm not able to capture the error that may occur if the "username" is not present in the example XML file..

    You have answered the question I asked in the topic.. so if required I'm happy to submit below question in new topic.

     

    To give you the background -

    Actually I'm trying to customize the error code and description sent to the client by DP. So I have created a XML file where I have defined DP generated error-code/sub-code, the customized error-code, and error description.

    So whenever the call fails at DP.. let's there is a JSON schema validation error.. the gateway script configured in error rule looks into the XML file and send the customized error-code and error description to the client.

    <?xml version="1.0"?>
    <codes>
     <errorCode>
      <dpCode>0x00230001-0x01d30003</dpCode>
      <usccCode>ERROR03</usccCode>
      <description>JSON Schema Validation Error.</description>
     </errorCode>
     <errorCode>
      <dpCode>0x01130006-0x00000000</dpCode>
      <usccCode>ERROR04</usccCode>
      <description>Failed to establish backside connection.</description>
     </errorCode>
    </codes>

     

    Now, in case, the DP generated error code is missing/not-defined in XML file then client does not get anything.. it gets empty JSON response. So for such scenarios I want to send generic customized code to client which will make me aware as well to re-verify the XML.

     

    Please advise.

     

    Thanks,

    Rohit

    Store the XML result in a variable, then do "if{...}else{...}" to write the wanted JSON response depending on whether result found match or not.

    Updated on 2019-07-31T07:53:06Z at 2019-07-31T07:53:06Z by HermannSW
  • rohit_dp
    rohit_dp
    19 Posts

    Re: DataPower - Gateway script to read all subchild elements from the child element if matches the condition

    ‏2019-08-02T18:28:40Z  
    • HermannSW
    • ‏2019-07-31T07:52:41Z

    Store the XML result in a variable, then do "if{...}else{...}" to write the wanted JSON response depending on whether result found match or not.

    Thanks, Hermann!

     

    I did what you suggested.. stored XML in a variable; converted into string and then search the string to see I the DP errorCode is there or not.

  • swlinn
    swlinn
    1445 Posts

    Re: DataPower - Gateway script to read all subchild elements from the child element if matches the condition

    ‏2019-08-15T17:36:31Z  
    • rohit_dp
    • ‏2019-08-02T18:28:40Z

    Thanks, Hermann!

     

    I did what you suggested.. stored XML in a variable; converted into string and then search the string to see I the DP errorCode is there or not.

    I'm a little late to this discussion, but why not XPath using 

    expression': "'/access/id[pw/OutputCredential/username='"+user+"']" which will return a nodeset of the id element that matches, and then you can use the DOM API functions, so if the xpath returned a nodelist in a variable named parentNode, 

                            var childNode = parentNode.item(0),firstChild();
                            while (childNode) {
                                // do something here with the current child node ... childNode.textContent should have the value, childNode.nodeName would be the element name, etc
                                childNode = childNode.nextSibling();
                            }

    Regards,
    Steve