XML type substitution

In an XML schema instance there is an option to re-declare an element type to something other than the stated type within the schema definition. This is indicated by an additional xsi:type attribute in the XML instance whose value indicates the name of the type to validate the element against.

This type must be a globally defined type in the schema definition. It must also be the type that is defined or a type that is derived from the defined type.

See http://www.w3.org/TR/xmlschema-0/#UseDerivInInstDocs.

This offers a detailed description of type substitution.

For example, having defined an element as myElement to be type base_type, and type base_type has a derived type derived_type:

<xsd:element name="myElement" type="base_type"/>
<xsd:complexType name="base_type">
          <xsd:sequence>
                    <xsd:element name="myChild1" type="xsd:string"/>
          </xsd:sequence>
</xsd:complexType>
<xsd:complexType name="derived_type">
          <xsd:complexContent>
                    <xsd:extension base="base_type">
                              <xsd:sequence>
                                        <xsd:element name="myChild2" type="xsd:string"/>
                              </xsd:sequence>
                    </xsd:extension>
          </xsd:complexContent>
</xsd:complexType>  

This XML instance would be valid:

<myElement><myChild1/></myElement>

A re-declaration of the defined type is also valid:

<myElement xsi:type="base_type"><myChild1/></myElement>

To re-declare the myElement type from base_type to derived_type, you must have the child elements for type derived_type. You must also have the xsi:type attribute in your XML instance. For example:

<myElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="derived_type">
          <myChild1/>
          <myChild2/>
</myElement>

Configuring a successful XML substitution

The XML substitute function works correctly when it is on the translation's source side. However, when the XML substitute function is used on the translation's destination side, an "Invalid path error" is given.

For example:

  1. Use the substitute function on the xlate destination side. In the xlate file HL7 > XML:
    { { OP COPY } 
     { ERR 0 }
     { IN {{0(0).MSH(0).#3(0).[0]}} }
     { OUT topElem.customer{kundeinfoType}.name.#text }
    }
    { { OP COPY } 
     { ERR 0 }
     { IN {{0(0).MSH(0).#3(0).[0]}} }
     { OUT topElem.customer{kundeinfoType}.&gender }
    }
    test data:
    MSH|^~\&|HIS||||20090603090227||ADT^A03|20090603090227|P|2.1||| EVN|A03|20090603090227||| PID|||200062||
    Irving^Bethany^Jo||19910125|F||2106-3|1290 RIVERSIDE DR^^IRVING^TX^75039|439|||ENGLISH|S|SPI|3000014|123335566|| 
    PV1||I||A|||10091|10091|00000^00000^00000^00000|MED||||7|||10091^Einstein^Albert^^^Dr.|IE|1|CI|||||||||||||||||||
    AA|||||200905110906|200906030859|3121800|3121800|||
    

    When you use hcixlttest, there is an invalid path:

    [0:TEST] Invalid path: topElem.customer{kundeinfoType}.name.#text - Type substitution {kundeinfoType} 
    was not found in instance.
  2. Now use substitute on the xlate source side.
    In xlate file xml--->hl7
    { { OP COPY } 
     { ERR 0 }
     { IN topElem.customer{kundeinfoType}.name.#text }
     { OUT {{0(0).PID(0).#5(0).[0]}} }
    }
    { { OP COPY } 
     { ERR 0 }
     { IN topElem.customer{kundeinfoType}.0.kundeitem.#text }
     { OUT {{0(0).PID(0).#5(0).[1]}} }
    }
    test data:
    <?xml version="1.0" encoding="UTF-8"?>
    <topElem>
     <customer xsi:type="kundeinfoType" gender="male" >
     <name>John Smith navn</name>
     <kundeitem>hhhkunde</kundeitem>
     </customer>
    </topElem>

There is now no error when running hcixlttest. The XML substitute function works correctly.