Concatenating Xpath values

LegacyForumLegacyForum Posts: 1,669 ✭✭
edited December 2016 in SOAtest
Hey guys is there a way to take the xpath values given from a xml-databank (say Test 1:z0 & Test 1: z1) and concatenate or join them together for later use. Or possibly as a script? I looked through the scriptingAPI for a join or concat function, but I didn't look too hard .

Thanks in advance,

LeapTester
Tagged:

Comments

  • LegacyForumLegacyForum Posts: 1,669 ✭✭
    LeapTester,

    It looks like the values you are trying to concatenate are coming from the same test (Test 1); a nice way of concatenating the values into one is by modifying the XPath you are using. Try something like this:

    /*[local-name(.)="Envelope" and namespace-uri(.)="http://schemas.xmlsoap.org/soap/envelope/"]/*[local-name(.)="Body" and namespace-uri(.)="http://schemas.xmlsoap.org/soap/envelope/"]/*[local-name(.)="getItemByIdResponse" and namespace-uri(.)="http://www.parasoft.com/wsdl/store-01/"]/*[local-name(.)="Result" and namespace-uri(.)="http://www.parasoft.com/wsdl/store-01/"]/*[local-name(.)="id" and namespace-uri(.)="" or local-name(.)="quantity_in_stock"]

    The part in bold shows what I've added to an automatically generated XPath. This concatenates the "id" and "quantity_in_stock" values into one. Let me know if this works with your setup.

    -Mike
  • LegacyForumLegacyForum Posts: 1,669 ✭✭
    sweet!!! thanks for the tip. I'll give it a try and let the community know.

    I should have recognized that and sorry for wasting bandwidth...

    thanks again,

    LeapTester
  • LegacyForumLegacyForum Posts: 1,669 ✭✭
    Hey Mike Thanks again. You've inspired me to try something a bit more slick than the "or". I am trying to parse a response where accounts and status' are part of a resposne node. I want to pull all the account which are active and use the result for further use. However i'm having an issue with an Xpath that I think should work.

    I tried this syntax on the xml snippet below, which passes the SoaTest validation check, but doesn't appear to match anything...

    Am I missing a slash?

    Thanks

    LeapTester

    /*/*/*/*/*/accountSearchResponse[accountStatus="ACTIVE"]/accountNumber

    CODE
    <?xml version="1.0" encoding="UTF-8"?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
     <accountSearchResponse xmlns="http://websvc.casino.adapter.csp.leapwireless.com">
      <AccountSearchResponseMsg>
       <searchResponse>
        <accountSearchResponse>
         <accountNumber>000102065327714</accountNumber>
         <lastname>JOHNSON</lastname>
         <firstName>DONNA</firstName>
         <middleInitial/>
         <accountStatus>ACTIVE</accountStatus>
         <accountName/>
        </accountSearchResponse>
       </searchResponse>
      </AccountSearchResponseMsg>
     </accountSearchResponse>
    </soapenv:Body>
    </soapenv:Envelope>
  • LegacyForumLegacyForum Posts: 1,669 ✭✭
    LeapTester,

    I'm currently looking into using something like this:

    CODE
    /*[local-name(.)="Envelope" and namespace-uri(.)="http://schemas.xmlsoap.org/soap/envelope/"]/*[local-name(.)="Body" and namespace-uri(.)="http://schemas.xmlsoap.org/soap/envelope/"]/*[local-name(.)="accountSearchResponse" and namespace-uri(.)="http://websvc.casino.adapter.csp.leapwireless.com"]/*[local-name(.)="AccountSearchResponseMsg" and namespace-uri(.)="http://websvc.casino.adapter.csp.leapwireless.com"]/*[local-name(.)="searchResponse" and namespace-uri(.)="http://websvc.casino.adapter.csp.leapwireless.com"]/*[local-name(.)="accountSearchResponse" and namespace-uri(.)="http://websvc.casino.adapter.csp.leapwireless.com"]/*[local-name(.)="accountStatus" and namespace-uri(.)="http://websvc.casino.adapter.csp.leapwireless.com"][.="ACTIVE"]


    I'll be able to update you with another XPath string tomorrow.

    -Mike
  • LegacyForumLegacyForum Posts: 1,669 ✭✭
    Hey big guy, no problems. i'm trying to work the predicate approach because i'm basically lazy and I like the short syntax involved. Any help is appreciated.

    Best,

    LeapTester
  • LegacyForumLegacyForum Posts: 1,669 ✭✭
    LeapTester,

    I'm attaching an example SOAtest project that uses your XML and is able to do what your looking for. I made two different tests that should be good examples for you to look at.

    Each example has an Edit tool to show you what was selected by the transformer. If you change the XML input so that "ACTIVE" is something else, you'll notice that the transformer doesn't select anything.

    Let me know if this is not what your looking for.

    -Mike
  • LegacyForumLegacyForum Posts: 1,669 ✭✭

    Am I missing a slash?

    Thanks

    LeapTester

    /*/*/*/*/*/accountSearchResponse[accountStatus="ACTIVE"]/accountNumber

    The general tactic of using a predicate to compare the value of a child element is sound.

    However, the XPath returns nothing because the XML elements of interest use namespaces. Therefore, you cannot use the /tagName syntax. You must use the /prefix:tagName syntax. Currently there is no way to map prefixes to namespaces, so the simplest XPath you can now create ignores namespaces by using /*:tagName.

    Here is an XPath to get what you want, simplified to find the element anywhere in the document instead of only if at a certain depth.

    //*:accountSearchResponse[*:accountStatus = "ACTIVE"]/*:accountNumber
  • LegacyForumLegacyForum Posts: 1,669 ✭✭

    LeapTester,

    It looks like the values you are trying to concatenate are coming from the same test (Test 1); a nice way of concatenating the values into one is by modifying the XPath you are using. Try something like this:

    /*[local-name(.)="Envelope" and namespace-uri(.)="http://schemas.xmlsoap.org/soap/envelope/"]/*[local-name(.)="Body" and namespace-uri(.)="http://schemas.xmlsoap.org/soap/envelope/"]/*[local-name(.)="getItemByIdResponse" and namespace-uri(.)="http://www.parasoft.com/wsdl/store-01/"]/*[local-name(.)="Result" and namespace-uri(.)="http://www.parasoft.com/wsdl/store-01/"]/*[local-name(.)="id" and namespace-uri(.)="" or local-name(.)="quantity_in_stock"]

    If you want to separate the values using a delimiter, then the simplest approach is to use an XPath with the string-join function. You don't need any scripting API.

    string-join(
    (
    //*:id,
    //*:quantity_in_stock
    ),
    "|")

    The first argument to string-join is a sequence that contains both the id and quantity_in_stock elements. string-join combines all values in the first argument -- a sequence of values (contained within parentheses) -- by concatenating them together, with each value separated by the second argument, in this case "|". So if you had an id value of "xyz" and quantity_in_stock of "57", the XPath would return "xyz|57".

    If you know you want just a fixed number of values, you could also use the concat function:

    concat(//*:id, "|", //*:quantity_in_stock)
  • LegacyForumLegacyForum Posts: 1,669 ✭✭
    string-join was added as part of XPath 2.0.

    Here is the documentation:

    http://www.w3.org/TR/xpath-functions/#func-string-join
Sign In or Register to comment.