Custom XML Mapping

The custom XML schema mapping will try to fill the service context with the best possible data based on the XML file submitted.

The best way of using this mapping is to use the Trisotech Modeler Import XSD feature to generate data types that will directly be compatible with your XML files but it is not required as the mapping is not very complex and quite flexible.

Mapping Rules

The mapping is done following simple rules as follow:

  1. The input XML namespaces are completely ignored.

  2. The input XML to service context mapping is case insensitive.

  3. The input XML to service context mapping ignores spaces and non-alphanumeric characters.

  4. A service context match on an input XML attribute is always favored to a match on an input XML element.

  5. The service context hierarchy is expected to be the same as the input XML hierarchy.

  6. The service context input data are matched to the children of the input XML document root element. The match can be done on the input XML root element in the case that the service context contains a single input data of a matching name.

Top-Down example

Given an example DMN model that has a single input data called Customer with a type called tCustomer defined as follow:

custom xml mapping 1

Using this DMN model, the most direct XML document to submit would be:

 <root>
    <Customer ContactName="John Smith"  Email="john.smith@fakemail.com" CustomerID="244">
         <FullAddress Address="3100 Cote-Vertu" City="Montreal" Region="QC" Country="Canada"/>
    </Customer>
 </root>

Here the XML file does not contain certain information (like CompanyName, PostalCode), these would receive null in the DMN Context. Also, note here that the root document element name is completely irrelevant.

Equivalent input XML

To illustrate the flexibility of the mapping, here are a few examples that yields equivalent DMN contexts:

Adding XML namespaces (rule 1):

 <root xmlns:customer="http://schema.trisotech.com/customer" xmlns:address="http://schema.trisotech.com/address">
    <customer:Customer ContactName="John Smith" Email="john.smith@fakemail.com" CustomerID="244">
         <address:FullAddress Address="3100 Cote-Vertu" City="Montreal" Region="QC" Country="Canada"/>
    </customer:Customer>
 </root>

Using customer directly as the document root (rule 6)

 <Customer ContactName="John Smith" Email="john.smith@fakemail.com" CustomerID="244">
    <FullAddress Address="3100 Cote-Vertu" City="Montreal" Region="QC" Country="Canada"/>
 </Customer>

Changing the case of attributes (rule 2)

 <Customer contactName="John Smith" email="john.smith@fakemail.com" customerId="244">
    <Fulladdress address="3100 Cote-Vertu" city="Montreal" region="QC" country="Canada"/>
 </Customer>

Using special characters (rule 3)

<Customer ContactName="John Smith" Email="john.smith@fakemail.com" CustomerID="244">
   <Full-Address Address="3100 Cote-Vertu" City="Montreal" Region="QC" Country="Canada"/>
</Customer>

Using elements instead of attributes (rule 4)

 <Customer>
    <ContactName>John Smith</ContactName>
    <Email>john.smith@fakemail.com</Email>
    <CustomerID>244</CustomerID>
    <FullAddress>
         <Address>3100 Cote-Vertu</Address>
         <City>Montreal</City>
         <Region>QC</Region>
         <Country>Canada</Country>
    </FullAddress>
 </Customer>

Collections as input XML

In the Customer example, to fill the tCustomer→Rental Collection, the XML input will need to have multiple Rental xml elements. Here is an extended example with 2 rentals:

 <Customer ContactName="John Smith" Email="john.smith@fakemail.com" CustomerID="244">
    <FullAddress Address="3100 Cote-Vertu" City="Montreal" Region="QC" Country="Canada"/>
    <Rental From="2017-08-26T07:00:00Z" To="2017-08-28T17:00:00Z">
         <Car Type="Compact" Make="Toyota" Model="Yaris" Year="2014" Plate="ABC 123"/>
    </Rental>
    <Rental From="2017-09-16T07:00:00Z" To="2017-09-18T17:00:00Z">
         <Car Type="Compact" Make="Kia" Model="Rio" Year="2016" Plate="DEF 456"/>
    </Rental>
 </Customer>

Bottom-Up Example

It is also possible to start from an XML document and then craft a DMN model to take a decision on it.

 <?xml version="1.0" encoding="utf-8" ?>
 <decision-call>
  <RentalRequest>
      <From>2017-10-22T11:00:00</From>
      <To>2017-10-24T11:00:00</To>
      <Vehicle>Economy</Vehicle>
  </RentalRequest>

  <Customer xmlns="http://www.eu-rent.com/customer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eu-rent.com/customer Customer.xsd">
    <ContactName>Repeat Customer</ContactName>
    <CompanyName>Acme Corp</CompanyName>
    <Phone>555-555-5555</Phone>
    <Email>customer1@acme.org</Email>
    <FullAddress>
      <Address>555 Road St.</Address>
      <City>New York</City>
      <Region>NY</Region>
      <Country>United States</Country>
      <PostalCode>10282</PostalCode>
    </FullAddress>

    <Rental>
      <From>2016-09-12T07:00:00</From>
      <To>2016-09-14T09:00:00</To>
      <Car>
        <Type>Economy</Type>
        <Make>Kia</Make>
        <Model>Rio</Model>
        <Year>2014</Year>
        <Plate>ABC 2584</Plate>
      </Car>
    </Rental>
    <Rental>
      <From>2017-07-15T15:00:00</From>
      <To>2017-07-31T13:00:00</To>
      <Car>
        <Type>Economy</Type>
        <Make>Toyota</Make>
        <Model>Yaris</Model>
        <Year>2016</Year>
        <Plate>XYZ 1265</Plate>
      </Car>
    </Rental>
    <Rental>
      <From>2017-09-22T11:00:00</From>
      <To>2017-09-23T11:00:00</To>
      <Car>
        <Type>Compact</Type>
        <Make>Toyota</Make>
        <Model>Corola</Model>
        <Year>2015</Year>
        <Plate>WKZ 6532</Plate>
      </Car>
    </Rental>
  </Customer>
 </decision-call>

The easiest mapping for this document would be to create a single Input Data in the DMN Model called decision-call. This is not extremely business friendly and we can use the rule 3 to call our input Decision Call instead.

custom xml mapping 2

This Decision Call would need have an item definition (Data Type) defined as follow:

custom xml mapping 3

This is the most straight forward mapping possible but still not very business friendly as we will have the artifact of the Decision Call in the rules that we are going to write in the model.

A better approach is to use the rule 6 and instead declare two Input Data:

custom xml mapping 4

Now we have something much more business friendly and we can define two data types (item definitions) that are separate for Rental Request and Customer:

custom xml mapping 5
custom xml mapping 6

Using XPATH

By default, each service input is considered to be filled from the root of the submitted XML document.

It is also possible to use an XPATH query to specify more clearly which part of the XML document should be used to fill an input by adding a custom attribute on named XPATH.

custom xml xpath

The XPATH query does not support namespaces.

Using the example in the previous section for a query //Car to assign all the car, we would end up with a collection of cars.

It is important to make the input a collection if we are expecting multiple results from the XPATH query.