<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
  <sch:ns prefix="f" uri="http://hl7.org/fhir"/>
  <sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
  <!-- 
    This file contains just the constraints for the profile Shared Health Bundle for Messages
    It includes the base constraints for the resource as well.
    Because of the way that schematrons and containment work, 
    you may need to use this schematron fragment to build a, 
    single schematron that validates contained resources (if you have any) 
  -->
  <sch:pattern>
    <sch:title>f:Bundle</sch:title>
    <sch:rule context="f:Bundle">
      <sch:assert test="count(f:entry) &gt;= 3">entry: minimum cardinality of 'entry' is 3</sch:assert>
      <sch:assert test="count(f:entry) &lt;= 3">entry: maximum cardinality of 'entry' is 3</sch:assert>
    </sch:rule>
  </sch:pattern>
  <sch:pattern>
    <sch:title>Bundle</sch:title>
    <sch:rule context="f:Bundle">
      <sch:assert test="not(f:entry/f:search) or (f:type/@value = 'searchset')">entry.search only when a search (inherited)</sch:assert>
      <sch:assert test="not(f:total) or (f:type/@value = 'searchset') or (f:type/@value = 'history')">total only when a search or history (inherited)</sch:assert>
      <sch:assert test="count(for $entry in f:entry[f:resource] return $entry[count(parent::f:Bundle/f:entry[f:fullUrl/@value=$entry/f:fullUrl/@value and ((not(f:resource/*/f:meta/f:versionId/@value) and not($entry/f:resource/*/f:meta/f:versionId/@value)) or f:resource/*/f:meta/f:versionId/@value=$entry/f:resource/*/f:meta/f:versionId/@value)])!=1])=0">FullUrl must be unique in a bundle, or else entries with the same fullUrl must have different meta.versionId (inherited)</sch:assert>
      <sch:assert test="not(f:entry/f:request) or (f:type/@value = 'batch') or (f:type/@value = 'transaction') or (f:type/@value = 'history')">entry.request only for some types of bundles (inherited)</sch:assert>
      <sch:assert test="not(f:entry/f:response) or (f:type/@value = 'batch-response') or (f:type/@value = 'transaction-response')">entry.response only for some types of bundles (inherited)</sch:assert>
      <sch:assert test="count(f:entry/f:resource/f:Patient)&lt;=1">Cannot have no more than 1 patient in one message (inherited)</sch:assert>
      <sch:assert test="exists(f:entry[1]/f:resource/f:MessageHeader)">First entry must be a MessageHeader (inherited)</sch:assert>
      <sch:assert test="count(distinct(f:entry/f:resource/f:MedicationRequest/f:extension[@url='http://hl7.org/fhir/StructureDefinition/extension-Task.groupIdentifier'])/f:valueIdentifier/f:value)&lt;=1">GroupIdentifier values must all be the same within a message (inherited)</sch:assert>
      <sch:assert test="exists(f:entry[1]/f:resource/f:MessageHeader/f:meta[f:profile/@value='http://sharedhealth.exchange/fhir/StructureDefinition/interaction-messageheader-901'])">First entry must be a MessageHeader with the messageheader-901 profile</sch:assert>
      <sch:assert test="exists(f:entry[2]/f:resource/f:OperationOutcome)">Second entry must be an OperationOutcome</sch:assert>
    </sch:rule>
  </sch:pattern>
  <sch:pattern>
    <sch:title>Bundle.entry</sch:title>
    <sch:rule context="f:Bundle/f:entry">
      <sch:assert test="f:resource or f:request or f:response">must be a resource unless there's a request or response (inherited)</sch:assert>
      <sch:assert test="(not(exists(f:fullUrl)) and not(exists(f:resource))) or (exists(f:fullUrl) and exists(f:resource))">The fullUrl element must be present when a resource is present, and not present otherwise (inherited)</sch:assert>
      <sch:assert test="not(exists(f:fullUrl)) or not(exists(f:resource/f:id)) or starts-with(f:url/@value, f:resource/f:id/@value)">Full URL must end with resource id when present (inherited)</sch:assert>
    </sch:rule>
  </sch:pattern>
</sch:schema>
