<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: deltaV2.sch 4267 2008-02-05 21:36:24Z nigelw $ -->
<!-- Copyright (c) 2007, 2008 DeltaXML Ltd. All rights reserved -->

<!-- 
  A schematron schema for a 2-way delta2 format. This is a subset of the 3-way schema 
  This file contains general constraints, additional constraints will apply for the two
  cases of expanded and compressed files 
-->

<schema xmlns="http://www.ascc.net/xml/schematron">
  <ns prefix="deltaxml" uri="http://www.deltaxml.com/ns/well-formed-delta-v1"/>
  
  <pattern name="delta check">
    <rule context="/*">
      <assert test="@deltaxml:version='2.0'">Delta version must be 2.0</assert>
      <assert test="@deltaxml:content-type=('full-context', 'changes-only')">There must be a deltaxml:content-type attribute with one of the values 'full-context' or 'changes-only'</assert>
    </rule>
    
    <rule context="*[@deltaxml:deltaV2]">
      <assert test="matches(@deltaxml:deltaV2, '[AB!=]')">Delta values must contain only the characters A,B,!, and = </assert>
    </rule>
    
    <rule context="*[/*[@deltaxml:content-type='changes-only']]">
      <assert test="@deltaxml:deltaV2">For a changes only document, all elements must have a deltaxml:deltaV2 attribute</assert>
    </rule>
    
  </pattern>
  
  <pattern name="global rules">
 
    <rule context="*[contains(@deltaxml:deltaV2,'!=')]/*">
      <assert test="@deltaxml:deltaV2">All child elements of an element with @deltaxml:deltaV2 containing '!=' must have a delta attribute</assert>
    </rule>
    
    <rule context="*[ancestor::*[not(self::deltaxml:*)][not(contains(@deltaxml:deltaV2,'!='))]]
      [not(self::deltaxml:*)]
      [not(parent::deltaxml:attributes)]">
      <assert test="not(@deltaxml:deltaV2)">An element that is a descendant of a non-modified element cannot have a delta attribute</assert>
    </rule>
     
    <rule context="*[@deltaxml:deltaV2='A!=B']">
      <assert test="child::*[@deltaxml:deltaV2=('A','B','A!=B')]">An element with delta A!=B must have at least one child with delta A, B or A!=B</assert>
    </rule>
    
  </pattern>
  
  <pattern name="attribute rules">
    
    <rule context="*[parent::deltaxml:attributes]">
      <assert test="deltaxml:attributeValue">All elements representing attributes (i.e. child of deltaxml:attributes) must contain at least one deltaxml:attributeValue child</assert>
      <assert test="*[self::deltaxml:attributeValue]">For an element representing an attribute (i.e. child of deltaxml:attributes), the only child elements allowed are deltaxml:attributeValue elements</assert>
      <assert test="namespace-uri() ne ''">All elements representing attributes  (i.e. child of deltaxml:attributes) must be associated with a namespace</assert>
    </rule>
    
    <rule context="deltaxml:attributeValue">
      <assert test="ancestor::*[2][self::deltaxml:attributes]">A deltaxml:attributeValue element must be the grandchild of a deltaxml:attributes element</assert>
      <assert test="count(node())=count(text())">A deltaxml:attributeValue element must contain only text node(s)</assert>
      <assert test="count(text())&lt;=1">A deltaxml:attributeValue element must contain either 0 or 1 text node</assert>
      <assert test="not(contains(@deltaxml:deltaV2,'!='))">A deltaxml:attributeValue element must have a deltaV2 value that expresses equality</assert>
      <assert test="not(preceding-sibling::*[@deltaxml:deltaV2=current()/@deltaxml:deltaV2]) and 
        not(following-sibling::*[@deltaxml:deltaV2=current()/@deltaxml:deltaV2])">A deltaxml:attributeValue element must not have a sibling with the same deltaV2 value</assert>
    </rule>
    
    <rule context="deltaxml:attributes">
      <assert test="not(preceding-sibling::*)">A deltaxml:attributes element must be the first child of its parent element </assert>
      <assert test="@deltaxml:ordered='false'">The deltaxml:attributes element is always orderless</assert>
    </rule>
  </pattern>
  
  <pattern name="pcdata rules">
    
    <rule context="deltaxml:textGroup">
      <assert test="deltaxml:text">A deltaxml:textGroup must contain at least one deltaxml:text child</assert>
      <assert test="*[self::deltaxml:text]">There should be no children in a deltaxml:textGroup that are not deltaxml:text elements</assert>
    </rule>
    
    <rule context="deltaxml:text">
      <assert test="count(node())=count(text())">A deltaxml:text element must contain only text node(s)</assert>
      <assert test="count(text())&lt;=1">A deltaxml:text element must contain either 0 or 1 text node</assert>
      <assert test="not(contains(@deltaxml:deltaV2,'!='))">A deltaxml:text element must have a deltaV2 value that expresses equality</assert>
      <!-- isnt this next dealt with above? -->
      <assert test="parent::deltaxml:textGroup">A deltaxml:text element must always be a child of a deltaxml:textGroup element</assert>
    </rule>
  </pattern>
</schema>