- Print
Overview
A guide with tips and tricks for working with XML-based APIs
Tulip Connectors can be used to interact with many types of external data sources. This article focuses on HTTP APIs that exchange information using XML. This category includes SOAP APIs.
Sending XML Data in Tulip
To send XML content in the body of a request, use the $value$
notation to show that a parameter should be inserted.
For example, with the following in the Request Body field:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:mes="http://mes.myexample.com"
xmlns:get="http://getInfo.mes.myexample.com"
>
<soapenv:Header/>
<soapenv:Body>
<mes:getInfo>
<mes:in0>
<get:value1>$input1$</get:value1>
<get:value2>$input2$</get:value2>
</mes:in0>
</mes:getInfo>
</soapenv:Body>
</soapenv:Envelope>
and the values input1
and input2
as inputs to the Connector Function, a request is made with the values of input1
and input2
substituted into the Request Body.
This is shown in the Tulip Connector Function interface below:
Parsing XML Data in Tulip
A Simple API Example
Let's start with a simple example response from an XML API.
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
The following examples show how to access the various pieces of information within Tulip.
An extractor of:
/bookstore/book[1]/title
returns:
<title lang="en">Everyday Italian</title>
Note that arrays in XML are "1-indexed", meaning that the first element is in the "1" position, as opposed to JSON-query which is "0-indexed".
An extractor of:
/bookstore/book[1]/title/text()
returns:
Everyday Italian
Note that the /text()
function is used to extract the text value contained within the selected node.
An extractor of:
/bookstore/book[@category="children"][1]/title/text()
returns:
Harry Potter
Note that the selector has allowed us to search within the properties of a node.
These examples can be directly used in Tulip as shown below:
A SOAP API Example
Now let's examine a more complex case with namespaces, a typical feature of SOAP APIs.
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<soap:Body>
<ns1:getInfoResponse xmlns:ns1="http://mes.myexample.com">
<ns1:out>
<errorCode xmlns="http://getInfo.mes.myexample.com">
0
</errorCode>
<errorMessage xmlns="http://getInfo.mes.myexample.com">
info retrieved successfully
</errorMessage>
<unitInfos xmlns="http://getInfo.mes.myexample.com">
<Info>
<currentOperation>My Operation</currentOperation>
<nextOperation>None</nextOperation>
<partName>1234567-890</partName>
<partRevision>B</partRevision>
<previousOperation xsi:nil="true"/>
<properties>
<Property>
<propertyName>PartNumber</propertyName>
<propertyValue>1234567-890</propertyValue>
</Property>
<Property>
<propertyName>PartRevision</propertyName>
<propertyValue>B</propertyValue>
</Property>
<Property>
<propertyName>PartDescription</propertyName>
<propertyValue>My example part</propertyValue>
</Property>
</properties>
<queueName xsi:nil="true"/>
<state>Normal</state>
</Info>
</unitInfos>
</ns1:out>
</ns1:getInfoResponse>
</soap:Body>
</soap:Envelope>
This response uses XML Namespaces, which add complexity. For most cases, a global search using the //*
and .//*
operators makes extraction very simple.
An extractor of:
//*[local-name()="propertyName"][1]/text()
returns:
PartNumber
Note that arrays in XML are "1-indexed", meaning that the first element is in the "1" position, as opposed to json-query which is "0-indexed".
An extractor of:
//*[local-name()="Property"]
returns:
<Property xmlns="http://getInfo.mes.myexample.com">
<propertyName>PartNumber</propertyName>
<propertyValue>1234567-890</propertyValue>
</Property>
<Property xmlns="http://getInfo.mes.myexample.com">
<propertyName>PartRevision</propertyName>
<propertyValue>B</propertyValue>
</Property>
<Property xmlns="http://getInfo.mes.myexample.com">
<propertyName>PartDescription</propertyName>
<propertyValue>My example part</propertyValue>
</Property>
Note here that the namespaces are "brought down" into this result. And therefore a sub-query would still search the global namespace.
To extract an Array of Objects, use the global search shown in the previous example to extract the array, and then a local search extractor of:
.//*[local-name()="propertyName"]/text()
to retrieve an array of objects of the form:
[
{
"Name": "PartNumber"
"Value": "1234567-890"
},
{
"Name": "PartRevision"
"Value": "B"
},
{
"Name": "PartDescription"
"Value": "My example part"
}
]
These examples are shown in the Tulip Connectors Interface below:
Did you find what you were looking for?
You can also head to community.tulip.co to post your question or see if others have faced a similar question!