/ Development  

The hidden power of reading externally hosted XML files

Hi there “Process Automation” fans,

Welcome to a new installment of “Process Automation” tips.

Sometimes you ask yourself a basic question which you validate with a colleague, and you both don’t have a clue about the answer. How do you read XML data from an external ONLINE source, just like you read XML data from the XML store!? Easy, right? Well…We were first thinking in file-connector terms, but that one doesn’t support URLs; only paths and network shares. So, what else? Well, it’s online; so, why not use a GET request over the HTTP connector…AHA! 🤗


Let’s get right into it…

First, two notes upfront:

  1. Most on-prem servers can’t access the internet like in this post. For this issue, you can use a proxy server (as “Middleman”) or use an SSH tunnel (as “Sneaky Path”). Both options are not for this post.
  2. Why read it from the interwebs when you can also download it and save it locally in the XMLStore? Great question, but what if the online version changes!? AHA!

There you go again…It all depends!

We’ll boot up our VM and in the meantime we need to search for an online XML resource. After a quick lunch walk with the dog, I found it on my own blog site behind this URL: https://appworks-tips.com/feed.xml

In the meantime, the VM is started. Dive into your workspace with the relevant project and add a new HTTP application connector as runtime reference (check the context menu of your project to accomplish this task!):

ext_xml_001

…AND create a new service group/container with that same HTTP connector:

ext_xml_002

You see a reference to an XML store location to serve config.xml in folder /OpenText/HttpConnector/. That’s something you create like this (including that xds_generic XML store definition):

ext_xml_003

The content of the config.xml file looks like this:

1
2
3
4
5
6
7
<configurations xmlns="http://httpconnector.opentext.com/1.0/configuration">
<connections>
<connection id="ext_location">
<url>https://appworks-tips.com</url>
</connection>
</connections>
</configurations>

After publication, you’ll find it here:

ext_xml_004

Don’t change it directly at this location, change it from within the solution. Other developers will benefit from the changes! You can use suffixes in the naming like config_dev.xml and config_tst.xml for other environments. Don’t forget to use the correct file for each service container in the relevant environment.

Now create a new custom webservice with this input:

  • Source: custom Web Service
  • Name: ws_external
  • Description: My great external service
  • Namespace: http://schemas/opa_tipsprj_generic/ws
  • Interface name: wsi_external
  • Implementation class: HttpConnector
  • Add a new operation: external

This will be the end result:

ext_xml_005

Our new operation requires an implementation like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
<implementation xmlns:c="http://schemas.cordys.com/cws/1.0" xmlns="http://httpconnector.opentext.com/1.0/implementation" xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" type="HTTP">
<connection-id>ext_location</connection-id>
<uri>/{0}</uri>
<http-method>GET</http-method>
<request-handler class="com.opentext.applicationconnector.httpconnector.impl.RestRequestHandler">
<uri-parameters>
<parameter type="xpath">./filename</parameter>
</uri-parameters>
</request-handler>
<response-handler class="com.opentext.applicationconnector.httpconnector.impl.RestResponseHandler" />
<valid-response-code>200</valid-response-code>
<namespaces />
</implementation>

What on earth do we do here? Well, this is the definition of your operation telling it to use the connection ID of our config.xml (in the HTTP connector); that’s our host URL. Then it pastes a URI behind it (in our case a variable parameter as XPath filename from our service call below!). Finally, it executes an HTTP GET request over two request/response classes, and expects a 200 value as a response (which is OK)

Right…Let’s publish, connect the service to the HTTP connector service group, restart the service container, and try it out; shall we?

1
2
3
4
5
6
7
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<external xmlns="http://schemas/opa_tipsprj_generic/ws">
<filename>feed.xml</filename>
</external>
</SOAP:Body>
</SOAP:Envelope>

Pitfall: <filename>test/feed.xml</filename> will result in URL: https://appworks-tips.com/test%2Ffeed.xml…that’s URL encoding in the connector which you can’t solve with something like this <filename><![CDATA[test/feed.xml]]></filename>; trust me (😇), I tried.

The result? Well, what about nice XML data to consume in your BPM:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<data>
<externalResponse xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas/opa_tipsprj_generic/ws">
<title xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">OpenText™ Process Automation Tips</title>
<icon xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">https://appworks-tips.com/images/favicon.png</icon>
<subtitle xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">Installments, thoughts, tricks and ideas</subtitle>
<link xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom" rel="self" href="https://appworks-tips.com/feed.xml" />
<link xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom" href="https://appworks-tips.com/" />
<updated xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">2026-04-15T06:02:52.601Z</updated>
<id xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">https://appworks-tips.com/</id>
<author xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">
<name>Antal Bos</name>
<uri>https://appworks-tips.com/</uri>
<email>contact@appworks-tips.com</email>
</author>
<generator xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom" uri="https://hexo.io/">Hexo</generator>
<entry xmlns:media="http://search.yahoo.com/mrss/" xmlns="http://www.w3.org/2005/Atom">
<title>How can it be? Cloning a service container via an ANT task</title>
<link rel="alternate" type="text/html" href="https://appworks-tips.com/2026/04/17/311_cloneservicecontainers_ant_task/" />
<link rel="enclosure" type="image/png" href="https://appworks-tips.com/images/posts/2026/311_cloneservicecontainers_ant_task/feature_tag.webp" />
<id>https://appworks-tips.com/2026/04/17/311_cloneservicecontainers_ant_task/</id>
<published>2026-04-17T12:00:00.000Z</published>
<updated>2026-04-15T06:02:52.601Z</updated>
<summary type="html">You'll find the answer in this post.</summary>
<media:thumbnail url="https://appworks-tips.com/images/posts/2026/311_cloneservicecontainers_ant_task/feature_tag.webp" />
<category term="Management" scheme="https://appworks-tips.com/categories/Management/" />
<category term="ProcessAutomation" scheme="https://appworks-tips.com/tags/ProcessAutomation/" />
<category term="OpenText" scheme="https://appworks-tips.com/tags/OpenText/" />
<category term="CLI" scheme="https://appworks-tips.com/tags/CLI/" />
<category term="CI/CD" scheme="https://appworks-tips.com/tags/CI-CD/" />
<category term="ANT" scheme="https://appworks-tips.com/tags/ANT/" />
</entry>
<!--Rest of the entries are removed...-->
</externalResponse>
</data>

That’s a PARTY!! 😎

Can we now also read JSON, as the HTTP connector serves both…right? Well, try it out yourself on https://appworks-tips.com/questions.json with this service call:

1
2
3
4
5
6
7
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP:Body>
<external xmlns="http://schemas/opa_tipsprj_generic/ws">
<filename>questions.json</filename>
</external>
</SOAP:Body>
</SOAP:Envelope>

Ohwwww mama…That’s working like a charm! This is exactly why I love to play with the OPA platform and all of its connectors!


Yes, nicely “DONE”. It has some after-smell on the URL encoding for XML parsing, but nothing we can’t overcome with multiple “workaround” configurations. Again, it’s interesting to see the power of the HTTP connector; it’s heavily underrated (in my opinion), but in the era of REST, you connect nearly anything to everything. These samples give a lot of confidence in the OPA platform, but be aware that you also need to implement the worst-case scenario once the “external source” is NOT giving a valid 200 response. Have a great weekend trying out this concept; we’ll continue our chat next week on another topic about “Process Automation Tips”.

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you can find out if you are also “The Process Automation guy”?