In an earlier post, we mentioned the use of Jitterbit’s XML functions to extract data without a formal Transformation component. In this post, we’ll show you how SelectSingleNode() can get text nodes without a Transformation.

SelectSingleNode() uses an XPath expression to query an XML tree and returns the resulting XML tree.
There are four node types within XML:

  • Element node: represents an XML element, a.k.a an XML tag.
  • Attribute node: represents an attribute from an element node, e.g. “href” attribute in
    <a href="http://www.example.com">example</a>
  • Comment node: represents comments in the document ().
  • Text node: represents the text enclosed in an element node. “example” in
    <p1>example</p1>

A short introduction to XPath is found at THE SCRAPINGHUB BLOG. There’s a handy XPath Playground there as well. Note the use of the text() in the expression below.

  $securityToken=SelectSingleNode(
    ReadFile("<TAG>Sources/SAML Response</TAG>"),	  
    "/S:Envelope/S:Body/wst:RequestSecurityTokenResponse/wst:RequestedSecurityToken/wsse:BinarySecurityToken/text()",		
    "S=http://www.w3.org/2003/05/soap-envelope",
    "wst=http://schemas.xmlsoap.org/ws/2005/02/trust",
    "wsse=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
  );

Where the “SAML Response” source (for use with SharePoint Online API) might be

<?xml version="1.0" encoding="utf-8"?>
<S:Envelope xmlns:wsa="http://www.w3.org/2005/08/addressing"
  xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
  xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
  xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
  xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust"
  xmlns:S="http://www.w3.org/2003/05/soap-envelope">
  <S:Header>
    <!— … —>
  </S:Header>
  <S:Body xmlns:S="http://www.w3.org/2003/05/soap-envelope">
    <wst:RequestSecurityTokenResponse
       xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
       xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
       xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">
      <wst:RequestedSecurityToken>
        <wsse:BinarySecurityToken Id="Compact0"
           xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">t=EwD4Ak6hBwAUoI9qUOm+nWxx1GEBzUSgrucLnssAAQ1NxGaoLXve85vgXcIYfaC7elbEE91PM5+hZzmu69rWwbcxHcABqL7+sXXxlvXebSOH420l9xdNrKUie9gKxXC0QlunzcPayQYblVmOvJaML7ILUXVyX9E2wLfsgaQcaU5gODa/R4Z7BOe3FqgEu7ddrQRHf7vjeyDXPhgVdaVaqtIRbBFh1A7/6ArrQdry00//oNqZOcMl88DeMzFDXqtLPU5pOEWPQcIuDr/uubjTDAPdWnK3K59+Tb0/xGkKTuBR90UkvSI3O3Eo74b3hVC1RayehWmp9N58Rj4/EGPsHCBnosKVreTIqMdbbu0X4VIRnBlJQcwJJ6JFDlJ8FngDZgAACJXfl0r9SfODyAFPng5uDus08hfu039l98kLVOkr6tyNz8BgA5VFpllV9+fyDdVdB6N6gqr/E8lstCAw/JU8XYOh9gKIpJZY8v2JjLr9aHmMSVhmj27e3i/1xKJ1usmQVy2ZdiCitQBLxy2qMkpdm76FHJ7F6zuuKRFPSxJANKhztGfcONLvYQmvEkHXMXORImBn9on75oMYYwQO/dkACJ7xO/Z847iomgouXSrMA0DEkIRBil6c0Ov+rwTuNibV4J0iZH5R5gL5EPBrQpjk1zg8K7VWCMURm+Fof/cV55h4I9F0JWpqz9YCcFwFHBKMeVHrxMHzsBE5aMhvtCTiUeCWau3jCWa1m5/f9ssQ2t9IWQXHThs/EaTE24g69FvLKrbCFnBuAOYWtmDN66IBPHxIgsDrRb9ZBRxl2p5hPVfftoOcf2NtTfLAWA1b9zj9U5woB++VxHPRPE+O9dL1kaLn8sSmsB+A+nw2gnzaKjjuK6yNScQUgLe8NhI9wCzl2gJKGZTArRixRSansAnrwGmhQYAYV8O4T8i0Yi0DKXJOUPoRlDNKTT2bJS3iaOpr+Lp+OvxKUoh7tFn60TuT8xtKtIiMeRKJfi5buhtNI3yqTVVDAg==&amp;p=</wsse:BinarySecurityToken>
      </wst:RequestedSecurityToken>
      <!— … —>
    </wst:RequestSecurityTokenResponse>
  </S:Body>
</S:Envelope>

I would be remiss if I didn’t mention a problem I faced recently using XPath and the XML below. Jitterbit support helped me out. (There’s a reason their support has ranked high —Thank you Tim D!)

You will sometimes need to access nodes using the local-name() and namespace-uri() attributes. Since the desired node in the XML (Salesforce outbound message) below uses a default namespace —without a prefix, using plain XPath— you can only access them this way. See this StackOverflow post

Here’s the final use of SelectSingleNode()

  $OrganizerKey = SelectSingleNode(
    $jitterbit.api.request.body, 
    '/soapenv:Envelope/soapenv:Body/*[local-name()="notifications"]/*[local-name()="Notification"]/*[local-name()="sObject"]/sf:Organizer_Key__c/text()', 
    'soapenv=http://schemas.xmlsoap.org/soap/envelope/',
    'sf=urn:sobject.enterprise.soap.sforce.com'
  );

..and the Salesforce Outbound message ($jitterbit.api.request.body)

<?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>
    <notifications xmlns="http://soap.sforce.com/2005/09/outbound">
      <OrganizationId>00D300000000D1kEAE</OrganizationId>
      <ActionId>04k0e0000004DPBAA2</ActionId>
      <SessionId xsi:nil="true"/>
      <EnterpriseUrl>https://my.salesforce.com/services/Soap/c/49.0/004300000000C1k</EnterpriseUrl>
      <PartnerUrl>https://my.salesforce.com/services/Soap/u/49.0/004300000000C1k</PartnerUrl>
      <Notification>
        <Id>05l0f000048mQwcAAE</Id>
        <sObject xsi:type="sf:Event__c"
       		 xmlns:sf="urn:sobject.enterprise.soap.sforce.com">
          <sf:Id>a0A0e00000evHacEAE</sf:Id>
          <!-- ... -->
          <sf:Organizer_Key__c>8445696667310260000</sf:Organizer_Key__c>
          <!-- ... -->
        </sObject>
      </Notification>
    </notifications>
  </soapenv:Body>
</soapenv:Envelope>