Multi-Version Batching in ETP Pharmacy Downloads
Draft for discussion – v0.5
Damian Murphy, 10 June 2005
Introduction
[MVBI] describes a general mechanism for handling batch content in HL7 messages, where the types (multiple versions) of batch items are unknown at design time. An example of this is found in ETP, where a pharmacy may be nominated dispenser for patients from a number of differently-versioned prescribing systems. This document describes such a case in detail.
Scenario
In the case where a patient presents a prescription token to a pharmacist, the pharmacy system will request that prescription, singly, from the ETP service. In the case where the pharmacist is nominated (for example, at the patient’s request), the pharmacy will request from the ETP service those prescriptions expected to be collected. These scenarios are described in detail in storyboards 2.2 and 2.3 in [M4MM].
In the case where the pharmacist receives nominated prescriptions from more than one prescriber, there will be periods where more than one version of the prescription message must be handled. For the pharmacy system itself, this situation is covered by the ETP version management approach, which requires any message receivers to be able to process any extant version. For the nominated pharmacy download itself, there is a need for a way to carry multiple versions of prescription messages, since the alternative is for the pharmacy system to know which versions are extant, and separately to request prescriptions for each version.
For nominated pharmacy downloads, prescriptions are returned by ETP in date order, without regard to version. Use of the “type-grouped” batch pattern would impose an unacceptable performance penalty on the ETP service, and break the required ordering. As such, the “flat-type” pattern is used.
The Batch Pattern and the PrescriptionReleaseResponse Model
The “flat-type batch pattern” is given in [MVBI] as:
Figure 1. Batch Pattern
The pattern is used as a framework, around which are built the application-specific requirements. In this case, the PrescriptionReleaseResponse model is constructed by adding structures to support the prescription download application. The “BatchPayload” and “AbstractBatchContent” classes are also renamed for clarity:
Figure 2. Example implementation: PrescriptionReleaseResponse
The AbstractPrescriptionResponse is never instantiated. [M3110MM] has an explicit model of a prescription download response that contains a single, fixed prescription (of a single, fixed version) suitable for the patient-presents-token use case.
In the above model, each instance of PrescriptionResponse is founding a PrescriptionReleaseResponse/component element that identifies the type (version) of the content, then contains the content itself. Considering an HL7 payload model with PrescriptionReleaseResponse as the root element, and omitting the application-specific data and most of the structural attributes, we get the structure shown below.
<PrescriptionReleaseResponse>
<component typeCode="COMP">
<templateId root="OID.for.PrescriptionResponse.Versions"
extension="PORX_MT132004UKyy"/>
<PrescriptionResponse>
<!-- MiM 4.y prescription response -->
</PrescriptionResponse>
</component>
<component typeCode="COMP">
<templateId root="OID.for.PrescriptionResponse.Versions"
extension="PORX_MT132004UKzz"/>
<PrescriptionResponse>
<!-- MiM 4.z prescription response -->
</PrescriptionResponse>
</component>
<component typeCode="COMP">
<templateId root="OID.for.PrescriptionResponse.Versions"
extension="PORX_MT132004UKyy"/>
<PrescriptionResponse>
<!-- MiM 4.y prescription response -->
</PrescriptionResponse>
</component>
</PrescriptionReleaseResponse>
In this case, the nominated pharmacy has made a single, version-agnostic request to the ETP service. ETP has responded with a batch containing two “version yy” and one “version zz” prescriptions. The order in which versions are presented is not enforced in the message, so the component/sequenceNumber is omitted. Similarly, although this is implemented as a “batch” (as in a “batch response”) it is really more of an object query response with a multi-versioned result set. As such there is no specified batch control and the SET<II> BatchPayload/id element, which is included in the flat-typed pattern to support batch manifests, is omitted from the PrescriptionBatchHeader.
Pharmacy Systems Processing Model
The pharmacy system, as a message receiver, is required by ETP version management policy to be able to process both “version yy” and “version zz” of the PrescriptionResponse payload. The PrescriptionReleaseResponse message itself is implemented as a “placeholder”, as described in [MVBI] and is not re-versioned to handle the new prescription message version. The PrescriptionReleaseResponse/component class itself does not care about the details of the payload type, it merely carries an identifier[1] for its content type in the templateId[2] element.
On receipt of the PrescriptionReleaseResponse message, the pharmacy system will perform application-specific processing on the PrescriptionReleaseResponse, DownloadRequest and BatchInfo elements. For each PrescriptionReleaseResponse/component it finds, it will use the templateId/@extension attribute to determine the content of the component element, then pass the next element to the handler for that version.
XML Schema Documents and Transforms
The HL7 payload model shown in figure 2 uses an “abstract” class that is never instantiated. The inclusion of such classes is currently unsupported by the HL7 RMIM Designer tools and, as such, the standard XML schema generator will write an XML schema document for the model in figure 2 that includes the AbstractPrescriptionResponse as a concrete class (this XML schema document is given at appendix 1).
Whilst support for such abstract classes is an aim for improved modelling tools, in the meantime the “standard” output may be trivially converted into that required by post-processing with an XSL transform. This conversion follows the rule that the standard XML schema document is copied except that:
- Element declarations (<xs:element>) that have abstract types, the “any content model”, have <xs:any/> substituted for the standard element.
- Complex type declarations (<xs:complexType>) for abstract types are omitted.
The transform given at appendix 2 implements these copying rules. To support this interim solution, we adopt the naming convention shown in figures 1 and 2. Abstract classes are indicated by names of the form “Abstract*”. Assuming this, the transform gives the production XML schema document shown at appendix 3[3], with the “anyType” substitution highlighted.
Note that the use of this transform in a “flat-typed” instance of the pattern relies on the content model for the component act relationship being expressed in a sequence (i.e. child element ordering is enforced), and that there is a 1:1 relationship between component and abstract content elements.
Running The Placeholder Transform
It has been noted that the transform given does not work correctly when executed from within the Altova XMLspy 2004 environment. This is manifest in spurious XML Schema attributes being identified for xs:element declarations and xs:complexType definitions. At the time of writing, other versions of this popular XML software are untested. However, Altova also provides a standalone XSLT environment[4] that executes the transform correctly. Other XSLT engines, such as that provided by Saxon[5], should also work correctly and have the advantage over XMLspy of being able to work on a batch of schema inputs at once. It is unclear why XMLspy 2004 should exhibit this behaviour, and given that alternatives exist, the transform is not supported inside XMLspy 2004 and any other environments that exhibit similar behaviour.
Exception Handling and Failure-in-Detail
The current exception handling mechanism in the MiM “Infrastructure” domain assumes a single potential point of failure – or at least that any message content will result in errors that affect the entire payload. It does not support the concept of multiple content instances in the payload that might fail individually without invalidating the complete instance set.
It would be attractive to amend the ControlAct/reason/DetectedIssueEvent model to include an “id” and hence to permit a reported exception to include a pointer to its location. However such an approach is unavailable due to the impact of such changes on Programme timescales[6]. As such, a suboptimal but more pragmatic approach is to use a “batch failure” message to provide the functionality absent from the extant exception handling system:
Figure 3. Batch detail error reporting
This behaves in much the same way as the “DetectedIssueEvent” in the MiM “Infrastructure”, the difference being that there may be many BatchItemError instances, one for each type of error in the batch. The SET<II> id element carries the identifiers of the individual batch items in the original message, that exhibited that error.
This is a synthetic message type introduced merely to work around exception reporting for multiple-content messages. It is a short-term fix only.
References
[MVBI] Multi-Version Batch Implementation, v0.8, Damian Murphy, 8 June 2005
[M4MM] Medication Management domain, MiM 4.0a.
[M3110MM] Medication Management domain, MiM 3.1.10
Appendix 1. “Standard” Schema Output for example PrescriptionReleaseResponse
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema targetNamespace="urn:hl7-org:v3" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:hl7-org:v3" xmlns:hl7="urn:hl7-org:v3">
<xs:include schemaLocation="../dt/datatypes.xsd"/>
<xs:include schemaLocation="../voc/voc.xsd"/>
<xs:annotation>
<xs:documentation>
Generated using schema builder version 1.21p12.
Stylesheets:
RoseTreeToMIFStaticModel.xsl version: 1.1
SplitModels.xsl version: 1.1
AssocInMif.xsl version:1.1
StaticMifToXsd.xsl version 1.1</xs:documentation>
</xs:annotation>
<!--
*****************************************************************************************************************
* XML schema for message type .
* Generated by XMLITS version 1.21p12, Copyright (C) 2002, 2003 by Health Level 7, Inc.
*
* Copyright (c) 2002, 2003, Health Level Seven. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Health Level Seven.
* THIS SOFTWARE IS PROVIDED BY HEALTH LEVEL SEVEN, INC. AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
********************************************************************************************************************
-->
<xs:element name="PrescriptionReleaseResponse" type="PORX_MT122002UK30.PrescriptionReleaseResponse"/>
<xs:complexType name="PORX_MT122002UK30.PrescriptionReleaseResponse">
<xs:sequence>
<xs:element name="id" type="II"/>
<xs:element name="effectiveTime" type="TS"/>
<xs:element name="component" type="PORX_MT122002UK30.Component" maxOccurs="unbounded"/>
<xs:element name="pertinentInformation" type="PORX_MT122002UK30.PertinentInformation17" minOccurs="0" maxOccurs="2"/>
<xs:element name="inFulfillmentOf" type="PORX_MT122002UK30.InFulfillmentOf1"/>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ControlAct"/>
<xs:attribute name="classCode" type="ActClass" use="optional" default="INFO"/>
<xs:attribute name="moodCode" type="ActMood" use="optional" default="EVN"/>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"/>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.Component">
<xs:sequence>
<xs:element name="seperatableInd" type="BL"/>
<xs:element name="templateId">
<xs:complexType>
<xs:attribute name="root" use="required">
<xs:simpleType>
<xs:restriction base="uid">
<xs:enumeration value="2.16.840.1.113883.2.1.3.2.4.18.2"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="extension" use="required">
<xs:simpleType>
<xs:restriction base="st"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="assigningAuthorityName" type="st" use="optional"/>
<xs:attribute name="displayable" type="bl" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="abstractPrescriptionResponse" type="PORX_MT122002UK30.AbstractPrescriptionResponse"/>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ActRelationship"/>
<xs:attribute name="typeCode" type="ActRelationshipType" use="optional" default="COMP"/>
<xs:attribute name="contextConductionInd" type="bl" use="optional" default="false"/>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"/>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.AbstractPrescriptionResponse">
<xs:sequence>
<xs:element name="id" type="II"/>
<xs:element name="typeId" type="II" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ControlAct"/>
<xs:attribute name="classCode" type="ActClass" use="optional" default="INFO"/>
<xs:attribute name="moodCode" type="ActMood" use="optional" default="EVN"/>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"/>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.PertinentInformation17">
<xs:sequence>
<xs:element name="seperatableInd" type="BL"/>
<xs:element name="pertinentBatchInfo" type="PORX_MT122002UK30.BatchInfo"/>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ActRelationship"/>
<xs:attribute name="typeCode" type="ActRelationshipType" use="optional" default="PERT"/>
<xs:attribute name="contextConductionInd" type="bl" use="optional" default="true"/>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"/>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.BatchInfo">
<xs:sequence>
<xs:element name="code" type="CD"/>
<xs:element name="value" type="INT"/>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="Observation"/>
<xs:attribute name="classCode" type="ActClass" use="optional" default="OBS"/>
<xs:attribute name="moodCode" type="ActMood" use="optional" default="EVN"/>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"/>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.InFulfillmentOf1">
<xs:sequence>
<xs:element name="seperatableInd" type="BL"/>
<xs:element name="priorDownloadRequestRef" type="PORX_MT122002UK30.DownloadRequestRef"/>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ActRelationship"/>
<xs:attribute name="typeCode" type="ActRelationshipType" use="optional" default="FLFS"/>
<xs:attribute name="inversionInd" type="bl" use="optional" default="false"/>
<xs:attribute name="negationInd" type="bl" use="optional" default="false"/>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"/>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.DownloadRequestRef">
<xs:sequence>
<xs:element name="id" type="II"/>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ControlAct"/>
<xs:attribute name="classCode" type="ActClass" use="optional" default="INFO"/>
<xs:attribute name="moodCode" type="ActMood" use="optional" default="RQO"/>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"/>
</xs:complexType>
</xs:schema>
Appendix 2. “Placeholder” Transform
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output version="1.0" encoding="UTF-8" indent="yes"/>
<!--
Multi-Version-Placeholder-Transform
Version: 1.2, 9 June 2005
Damian Murphy <damian.murphy@npfit.nhs.uk>
NHS Connecting For Health NPfIT Comms & Messaging Team
Clone XML schema document, removing type declarations for abstract types, and replacing
abstract element declarations with xs:anyType content models.
TODO: Put a check into the "xs:any" model writer to make sure that the parent Act carries the HL7
templateId "attribute" (i.e. element declaration)
-->
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:variable name="aName" select="name()"/>
<xsl:attribute name="{$aName}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:for-each select="*">
<xsl:call-template name="process">
<xsl:with-param name="this" select="."/>
</xsl:call-template>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template name="process">
<xsl:param name="this"/>
<xsl:variable name="eName" select="name($this)"/>
<xsl:choose>
<!--
Just skip a complexType declaration for an Abstract type
-->
<xsl:when test="($eName = 'xs:complexType') and contains($this/@name,'.Abstract')"/>
<!--
Use <xs:any/> in place of an element declaration with an Abstract type
-->
<xsl:when test="($eName = 'xs:element') and contains($this/@type,'.Abstract')">
<xsl:element name="xs:any"/>
</xsl:when>
<!--
Otherwise just clone the node
-->
<xsl:otherwise>
<xsl:element name="{$eName}">
<xsl:for-each select="$this/@*">
<xsl:variable name="aName" select="name()"/>
<xsl:attribute name="{$aName}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:choose>
<xsl:when test="not($this/*)">
<xsl:value-of select="string($this)"/>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="$this/*">
<xsl:call-template name="process">
<xsl:with-param name="this" select="."/>
</xsl:call-template>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Appendix 3. Transformed XML Schema
document
<?xml version="1.0" encoding="UTF-8"?><!-- This is a non-standard "strict" version of an NPfIT schema, with optional elements made required and II/CV types tightened -->
<!-- It is provided "without prejudice" with no guarantee of fitness for any purpose -->
<!-- Produced by XSDStrictMaker v1.5, Definition file v1.2, Rik Smithies 15/04/2005 -->
<xs:schema xmlns="urn:hl7-org:v3" xmlns:hl7="urn:hl7-org:v3" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:hl7-org:v3" elementFormDefault="qualified">
<xs:include schemaLocation="../dt/datatypes.xsd"></xs:include>
<xs:include schemaLocation="../voc/voc.xsd"></xs:include>
<xs:annotation>
<xs:documentation>
Generated using schema builder version 1.21p12.
Stylesheets:
RoseTreeToMIFStaticModel.xsl version: 1.1
SplitModels.xsl version: 1.1
AssocInMif.xsl version:1.1
StaticMifToXsd.xsl version 1.1</xs:documentation>
</xs:annotation>
<xs:element name="PrescriptionReleaseResponse" type="PORX_MT122002UK30.PrescriptionReleaseResponse"></xs:element>
<xs:complexType name="PORX_MT122002UK30.PrescriptionReleaseResponse">
<xs:sequence>
<xs:element name="id" type="II" minOccurs="1" maxOccurs="1"></xs:element>
<xs:element name="effectiveTime" type="TS" minOccurs="1" maxOccurs="1"></xs:element>
<xs:element type="PORX_MT122002UK30.Component" minOccurs="1" maxOccurs="unbounded" name="component"></xs:element>
<xs:element type="PORX_MT122002UK30.PertinentInformation17" minOccurs="0" maxOccurs="2" name="pertinentInformation"></xs:element>
<xs:element type="PORX_MT122002UK30.InFulfillmentOf1" minOccurs="1" maxOccurs="1" name="inFulfillmentOf"></xs:element>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ControlAct"></xs:attribute>
<xs:attribute name="classCode" type="ActClass" use="required"></xs:attribute>
<xs:attribute name="moodCode" type="ActMood" use="required"></xs:attribute>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"></xs:attribute>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.Component">
<xs:sequence>
<xs:element name="seperatableInd" type="BL" minOccurs="1" maxOccurs="1"></xs:element>
<xs:element name="templateId">
<xs:complexType>
<xs:attribute name="root" use="required">
<xs:simpleType>
<xs:restriction base="uid">
<xs:enumeration value="2.16.840.1.113883.2.1.3.2.4.18.2"></xs:enumeration>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="extension" use="required">
<xs:simpleType>
<xs:restriction base="st"></xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="assigningAuthorityName" type="st" use="optional"></xs:attribute>
<xs:attribute name="displayable" type="bl" use="optional"></xs:attribute>
</xs:complexType>
</xs:element>
<xs:any/>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ActRelationship"></xs:attribute>
<xs:attribute name="typeCode" type="ActRelationshipType" use="required"></xs:attribute>
<xs:attribute name="contextConductionInd" type="bl" use="required"></xs:attribute>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"></xs:attribute>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.PertinentInformation17">
<xs:sequence>
<xs:element name="seperatableInd" type="BL" minOccurs="1" maxOccurs="1"></xs:element>
<xs:element type="PORX_MT122002UK30.BatchInfo" minOccurs="1" maxOccurs="1" name="pertinentBatchInfo"></xs:element>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ActRelationship"></xs:attribute>
<xs:attribute name="typeCode" type="ActRelationshipType" use="required"></xs:attribute>
<xs:attribute name="contextConductionInd" type="bl" use="required"></xs:attribute>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"></xs:attribute>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.BatchInfo">
<xs:sequence>
<xs:element name="code" type="CD" minOccurs="1" maxOccurs="1"></xs:element>
<xs:element name="value" type="INT" minOccurs="1" maxOccurs="1"></xs:element>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="Observation"></xs:attribute>
<xs:attribute name="classCode" type="ActClass" use="required"></xs:attribute>
<xs:attribute name="moodCode" type="ActMood" use="required"></xs:attribute>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"></xs:attribute>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.InFulfillmentOf1">
<xs:sequence>
<xs:element name="seperatableInd" type="BL" minOccurs="1" maxOccurs="1"></xs:element>
<xs:element type="PORX_MT122002UK30.DownloadRequestRef" minOccurs="1" maxOccurs="1" name="priorDownloadRequestRef"></xs:element>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ActRelationship"></xs:attribute>
<xs:attribute name="typeCode" type="ActRelationshipType" use="required"></xs:attribute>
<xs:attribute name="inversionInd" type="bl" use="required"></xs:attribute>
<xs:attribute name="negationInd" type="bl" use="required"></xs:attribute>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"></xs:attribute>
</xs:complexType>
<xs:complexType name="PORX_MT122002UK30.DownloadRequestRef">
<xs:sequence>
<xs:element name="id" type="II" minOccurs="1" maxOccurs="1"></xs:element>
</xs:sequence>
<xs:attribute name="type" type="Classes" default="ControlAct"></xs:attribute>
<xs:attribute name="classCode" type="ActClass" use="required"></xs:attribute>
<xs:attribute name="moodCode" type="ActMood" use="required"></xs:attribute>
<xs:attribute name="typeID" use="optional">
<xs:simpleType>
<xs:list itemType="oid"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="realmCode" use="optional">
<xs:simpleType>
<xs:list itemType="cs"></xs:list>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="nullFlavor" type="cs" use="optional"></xs:attribute>
</xs:complexType>
</xs:schema>
[1] Note that this will require the correct assignment of an OID to describe extant parent prescription message versions.
[2] After some discussion, the original “templateId”, rather than “typeId”, is used to carry this information. This is because in HL7 the “typeId” attribute is used to indicate the type of the “thing with the typeId” itself. The templateId attribute is used to provide typing information on what comes next.
[3] Note that the “standard output” at appendix 1 is the basic XML schema output that provides defaults for HL7 structural attributes. The “placeholder” transform will, however, work unchanged on “tightened” schemas that enforce the NPfIT constraints on structural attributes, as has happened with this example.
[4] Available free at http://www.altova.com/resources_freetools.html
[5] Available free at http://saxon.sourceforge.net/
[6] This is in part due to the current practice of tightly-coupling the wrapper structures to the payloads, an architectural flaw imposed by current tooling.