Summary: How to navigate over XML documents with reusable XPath expressions, including ones with namespaces.

Along with JSON Pointers, presented recently, all the features in the post will be released in Zato 2.0, which is currently in development on GitHub.

XPath expressions and XML namespaces can be defined once and reused in many services using the web admin GUI, API or enmasse. For instance, here are definitions needed to map identifiers between hypothetical ERP and CRM systems.


And that’s how a sample service may look like - notice that response is an empty document initially and all the required elements are created on fly, including placing them in namespaces defined in the GUI.

# -*- coding: utf-8 -*-

from __future__ import absolute_import, division, print_function, unicode_literals

# lxml
from lxml import etree

# Zato
from zato.server.service import Service

class IdMapper(Service):
    name = 'id.mapper2'

    def handle(self):

        # Obtain an XPath wrapper for the service's request
        req_xp = self.msg.xpath()

        # Get a couple of request elements
        cust_id = req_xp.get('ERP CustomerId')
        account_id = req_xp.get('ERP AccountId')

        # Prepare response and its associated XPath wrapper.
        resp = etree.Element('resp')
        resp_xp = self.msg.xpath(resp)

        # Map request elements into response
        resp_xp.set('CRM CustomerId', cust_id)
        resp_xp.set('CRM AccountId', account_id)

        # Set a constant value, note that in response XML namespaces
        # will be added as needed.
        resp_xp.set('CRM Provider', 'ABC')

        # Return response
        self.response.payload = etree.tostring(resp, pretty_print=True)

As always - that very code can be hot-deployed onto a cluster and re-configured on fly. Should any updates be needed to XPath expressions or namespaces used, no code changes will have to be performed - such a service is purely configuration-driven and can be exposed over multiple channels, such as HTTP, AMQP, ZeroMQ or JMS WebSphere MQ.