<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns:p="http://www.w3.org/2007/03/xproc" ns="http://www.w3.org/2007/03/xproc" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <!--
    This schema incorrectly prohibits xml:id and xml:base on extension
    elements and the contents of p:doc. They are allowed in those places.
  -->
  <define name="XPathExpression">
    <text/>
  </define>
  <define name="name.attr">
    <attribute name="name">
      <data type="NCName"/>
    </attribute>
  </define>
  <define name="port.attr">
    <attribute name="port">
      <data type="NCName"/>
    </attribute>
  </define>
  <define name="required.attr">
    <attribute name="required">
      <choice>
        <value>yes</value>
        <value>no</value>
      </choice>
    </attribute>
  </define>
  <define name="sequence.attr">
    <attribute name="sequence">
      <choice>
        <value>yes</value>
        <value>no</value>
      </choice>
    </attribute>
  </define>
  <define name="default.attr">
    <attribute name="default">
      <choice>
        <value>yes</value>
        <value>no</value>
      </choice>
    </attribute>
  </define>
  <define name="select.attr">
    <optional>
      <attribute name="select">
        <ref name="XPathExpression"/>
      </attribute>
    </optional>
  </define>
  <define name="ignore-prefixes.attr">
    <attribute name="p:ignore-prefixes">
      <data type="NMTOKENS"/>
    </attribute>
  </define>
  <define name="xmlid.attr">
    <attribute name="xml:id">
      <data type="ID"/>
    </attribute>
  </define>
  <define name="xmlbase.attr">
    <attribute name="xml:base">
      <data type="anyURI"/>
    </attribute>
  </define>
  <define name="href.attr">
    <attribute name="href">
      <data type="anyURI"/>
    </attribute>
  </define>
  <define name="common.attributes">
    <optional>
      <ref name="xmlid.attr"/>
    </optional>
    <optional>
      <ref name="xmlbase.attr"/>
    </optional>
  </define>
  <!-- ============================================================ -->
  <start>
    <ref name="Pipeline"/>
  </start>
  <!-- ============================================================ -->
  <define name="PipelineLibrary">
    <element name="pipeline-library">
      <ref name="common.attributes"/>
      <zeroOrMore>
        <choice>
          <ref name="Import"/>
          <ref name="DeclareStep"/>
          <ref name="Pipeline"/>
          <ref name="Doc"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="Import">
    <element name="import">
      <ref name="common.attributes"/>
      <ref name="href.attr"/>
      <zeroOrMore>
        <ref name="Doc"/>
      </zeroOrMore>
    </element>
  </define>
  <define name="Pipeline">
    <element name="pipeline">
      <optional>
        <attribute name="name">
          <data type="QName"/>
        </attribute>
      </optional>
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <zeroOrMore>
        <choice>
          <ref name="Input"/>
          <ref name="Output"/>
          <ref name="Parameter"/>
          <ref name="Import"/>
          <ref name="DeclareStep"/>
          <ref name="Doc"/>
        </choice>
      </zeroOrMore>
      <ref name="Subpipeline"/>
    </element>
  </define>
  <define name="Subpipeline">
    <zeroOrMore>
      <choice>
        <ref name="ForEach"/>
        <ref name="Viewport"/>
        <ref name="Choose"/>
        <ref name="Group"/>
        <ref name="Try"/>
        <ref name="OtherStep"/>
        <ref name="Doc"/>
        <ref name="Ignored"/>
      </choice>
    </zeroOrMore>
  </define>
  <!-- ============================================================ -->
  <define name="Input">
    <element name="input">
      <ref name="port.attr"/>
      <optional>
        <ref name="sequence.attr"/>
      </optional>
      <optional>
        <ref name="select.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <zeroOrMore>
        <choice>
          <ref name="Pipe"/>
          <ref name="Document"/>
          <ref name="Inline"/>
          <ref name="Doc"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="Output">
    <element name="output">
      <ref name="port.attr"/>
      <optional>
        <ref name="sequence.attr"/>
      </optional>
      <optional>
        <ref name="default.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <zeroOrMore>
        <choice>
          <ref name="Pipe"/>
          <ref name="Document"/>
          <ref name="Inline"/>
          <ref name="Doc"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="Pipe">
    <element name="pipe">
      <attribute name="step">
        <choice>
          <data type="QName"/>
          <data type="NCName"/>
        </choice>
      </attribute>
      <ref name="port.attr"/>
      <ref name="common.attributes"/>
      <zeroOrMore>
        <ref name="Doc"/>
      </zeroOrMore>
    </element>
  </define>
  <define name="Document">
    <element name="document">
      <ref name="href.attr"/>
      <ref name="common.attributes"/>
      <zeroOrMore>
        <ref name="Doc"/>
      </zeroOrMore>
    </element>
  </define>
  <define name="Inline">
    <element name="inline">
      <ref name="common.attributes"/>
      <ref name="Ignored"/>
    </element>
  </define>
  <!-- ============================================================ -->
  <define name="ValueOption">
    <element name="option">
      <attribute name="name">
        <choice>
          <data type="QName"/>
          <value>*</value>
          <data type="token">
            <param name="pattern">\*:.+</param>
          </data>
          <data type="token">
            <param name="pattern">.+:\*</param>
          </data>
        </choice>
      </attribute>
      <optional>
        <ref name="required.attr"/>
      </optional>
      <attribute name="value"/>
      <ref name="common.attributes"/>
      <zeroOrMore>
        <ref name="Doc"/>
      </zeroOrMore>
    </element>
  </define>
  <define name="SelectOption">
    <element name="option">
      <attribute name="name">
        <choice>
          <data type="QName"/>
          <value>*</value>
          <data type="token">
            <param name="pattern">\*:.+</param>
          </data>
          <data type="token">
            <param name="pattern">.+:\*</param>
          </data>
        </choice>
      </attribute>
      <optional>
        <ref name="required.attr"/>
      </optional>
      <optional>
        <ref name="select.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <interleave>
        <choice>
          <ref name="Pipe"/>
          <ref name="Document"/>
          <ref name="Inline"/>
        </choice>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
      </interleave>
    </element>
  </define>
  <define name="Option">
    <choice>
      <ref name="ValueOption"/>
      <ref name="SelectOption"/>
    </choice>
  </define>
  <!-- ============================================================ -->
  <define name="ValueParameter">
    <element name="parameter">
      <attribute name="name">
        <choice>
          <data type="QName"/>
          <value>*</value>
          <data type="token">
            <param name="pattern">\*:.+</param>
          </data>
          <data type="token">
            <param name="pattern">.+:\*</param>
          </data>
        </choice>
      </attribute>
      <optional>
        <ref name="required.attr"/>
      </optional>
      <attribute name="value"/>
      <ref name="common.attributes"/>
      <zeroOrMore>
        <ref name="Doc"/>
      </zeroOrMore>
    </element>
  </define>
  <define name="SelectParameter">
    <element name="parameter">
      <attribute name="name">
        <choice>
          <data type="QName"/>
          <value>*</value>
          <data type="token">
            <param name="pattern">\*:.+</param>
          </data>
          <data type="token">
            <param name="pattern">.+:\*</param>
          </data>
        </choice>
      </attribute>
      <optional>
        <ref name="required.attr"/>
      </optional>
      <optional>
        <ref name="select.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <interleave>
        <choice>
          <ref name="Pipe"/>
          <ref name="Document"/>
          <ref name="Inline"/>
        </choice>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
      </interleave>
    </element>
  </define>
  <define name="Parameter">
    <choice>
      <ref name="ValueParameter"/>
      <ref name="SelectParameter"/>
    </choice>
  </define>
  <!-- ============================================================ -->
  <define name="ImportParameter">
    <element name="import-parameter">
      <attribute name="name">
        <choice>
          <data type="QName"/>
          <value>*</value>
          <data type="token">
            <param name="pattern">\*:.+</param>
          </data>
          <data type="token">
            <param name="pattern">.+:\*</param>
          </data>
        </choice>
      </attribute>
      <ref name="common.attributes"/>
      <zeroOrMore>
        <ref name="Doc"/>
      </zeroOrMore>
    </element>
  </define>
  <!-- ============================================================ -->
  <define name="DeclareStep">
    <element name="declare-step">
      <attribute name="type">
        <data type="QName"/>
      </attribute>
      <ref name="common.attributes"/>
      <zeroOrMore>
        <ref name="Input"/>
        <ref name="Output"/>
        <ref name="Parameter"/>
        <ref name="Doc"/>
      </zeroOrMore>
    </element>
  </define>
  <!-- ============================================================ -->
  <define name="ForEach">
    <element name="for-each">
      <optional>
        <ref name="name.attr"/>
      </optional>
      <optional>
        <ref name="select.attr"/>
      </optional>
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <group>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
        <optional>
          <ref name="IterationSource"/>
        </optional>
        <zeroOrMore>
          <choice>
            <ref name="Output"/>
            <ref name="Parameter"/>
            <ref name="Doc"/>
          </choice>
        </zeroOrMore>
        <ref name="Subpipeline"/>
      </group>
    </element>
  </define>
  <define name="IterationSource">
    <element name="iteration-source">
      <optional>
        <ref name="select.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <zeroOrMore>
        <choice>
          <ref name="Pipe"/>
          <ref name="Document"/>
          <ref name="Inline"/>
          <ref name="Doc"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <!-- ============================================================ -->
  <define name="Viewport">
    <element name="viewport">
      <optional>
        <ref name="name.attr"/>
      </optional>
      <attribute name="match">
        <ref name="XPathExpression"/>
      </attribute>
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <group>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
        <optional>
          <ref name="ViewportSource"/>
        </optional>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
        <ref name="Output"/>
        <zeroOrMore>
          <choice>
            <ref name="Parameter"/>
            <ref name="Doc"/>
          </choice>
        </zeroOrMore>
        <ref name="Subpipeline"/>
      </group>
    </element>
  </define>
  <define name="ViewportSource">
    <element name="viewport-source">
      <ref name="common.attributes"/>
      <interleave>
        <choice>
          <ref name="Pipe"/>
          <ref name="Document"/>
          <ref name="Inline"/>
        </choice>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
      </interleave>
    </element>
  </define>
  <!-- ============================================================ -->
  <define name="Choose">
    <element name="choose">
      <optional>
        <ref name="name.attr"/>
      </optional>
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <group>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
        <optional>
          <ref name="XPathContext"/>
        </optional>
        <zeroOrMore>
          <choice>
            <ref name="When"/>
            <ref name="Doc"/>
          </choice>
        </zeroOrMore>
        <optional>
          <ref name="Otherwise"/>
        </optional>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
      </group>
    </element>
  </define>
  <define name="XPathContext">
    <element name="xpath-context">
      <ref name="common.attributes"/>
      <interleave>
        <choice>
          <ref name="Pipe"/>
          <ref name="Document"/>
          <ref name="Inline"/>
        </choice>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
      </interleave>
    </element>
  </define>
  <define name="When">
    <element name="when">
      <attribute name="test">
        <ref name="XPathExpression"/>
      </attribute>
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <group>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
        <optional>
          <ref name="XPathContext"/>
        </optional>
        <zeroOrMore>
          <choice>
            <ref name="Output"/>
            <ref name="Parameter"/>
            <ref name="Doc"/>
          </choice>
        </zeroOrMore>
        <ref name="Subpipeline"/>
      </group>
    </element>
  </define>
  <define name="Otherwise">
    <element name="otherwise">
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <group>
        <zeroOrMore>
          <choice>
            <ref name="Output"/>
            <ref name="Parameter"/>
            <ref name="Doc"/>
          </choice>
        </zeroOrMore>
        <ref name="Subpipeline"/>
      </group>
    </element>
  </define>
  <!-- ============================================================ -->
  <define name="Group">
    <element name="group">
      <optional>
        <ref name="name.attr"/>
      </optional>
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <group>
        <zeroOrMore>
          <choice>
            <ref name="Output"/>
            <ref name="Parameter"/>
            <ref name="Doc"/>
          </choice>
        </zeroOrMore>
        <ref name="Subpipeline"/>
      </group>
    </element>
  </define>
  <!-- ============================================================ -->
  <define name="Try">
    <element name="try">
      <optional>
        <ref name="name.attr"/>
      </optional>
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <group>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
        <ref name="Group"/>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
        <ref name="Catch"/>
        <zeroOrMore>
          <ref name="Doc"/>
        </zeroOrMore>
      </group>
    </element>
  </define>
  <define name="Catch">
    <element name="catch">
      <optional>
        <ref name="name.attr"/>
      </optional>
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <ref name="common.attributes"/>
      <group>
        <zeroOrMore>
          <choice>
            <ref name="Output"/>
            <ref name="Parameter"/>
            <ref name="Doc"/>
          </choice>
        </zeroOrMore>
        <ref name="Subpipeline"/>
      </group>
    </element>
  </define>
  <!-- ============================================================ -->
  <define name="OtherAtomicStep">
    <element>
      <anyName>
        <except>
          <name>p:pipeline</name>
          <name>p:pipeline-library</name>
          <name>p:import</name>
          <name>p:declare-step</name>
          <name>p:input</name>
          <name>p:output</name>
          <name>p:parameter</name>
          <name>p:import-parameter</name>
          <name>p:pipe</name>
          <name>p:document</name>
          <name>p:inline</name>
          <name>p:for-each</name>
          <name>p:iteration-source</name>
          <name>p:viewport</name>
          <name>p:viewport-source</name>
          <name>p:choose</name>
          <name>p:xpath-context</name>
          <name>p:when</name>
          <name>p:otherwise</name>
          <name>p:group</name>
          <name>p:try</name>
          <name>p:catch</name>
          <name>p:doc</name>
          <nsName ns="http://www.w3.org/1999/xhtml"/>
        </except>
      </anyName>
      <optional>
        <ref name="name.attr"/>
      </optional>
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <zeroOrMore>
        <choice>
          <ref name="Input"/>
          <ref name="Output"/>
          <ref name="ImportParameter"/>
          <ref name="Option"/>
          <ref name="Parameter"/>
          <ref name="Doc"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="OtherCompoundStep">
    <element>
      <anyName>
        <except>
          <name>p:pipeline</name>
          <name>p:pipeline-library</name>
          <name>p:import</name>
          <name>p:declare-step</name>
          <name>p:input</name>
          <name>p:output</name>
          <name>p:parameter</name>
          <name>p:import-parameter</name>
          <name>p:pipe</name>
          <name>p:document</name>
          <name>p:inline</name>
          <name>p:for-each</name>
          <name>p:iteration-source</name>
          <name>p:viewport</name>
          <name>p:viewport-source</name>
          <name>p:choose</name>
          <name>p:xpath-context</name>
          <name>p:when</name>
          <name>p:otherwise</name>
          <name>p:group</name>
          <name>p:try</name>
          <name>p:catch</name>
          <name>p:doc</name>
          <nsName ns="http://www.w3.org/1999/xhtml"/>
        </except>
      </anyName>
      <optional>
        <ref name="name.attr"/>
      </optional>
      <optional>
        <ref name="ignore-prefixes.attr"/>
      </optional>
      <group>
        <zeroOrMore>
          <choice>
            <ref name="Input"/>
            <ref name="Output"/>
            <ref name="ImportParameter"/>
            <ref name="Option"/>
            <ref name="Parameter"/>
            <ref name="Doc"/>
          </choice>
        </zeroOrMore>
        <ref name="Subpipeline"/>
      </group>
    </element>
  </define>
  <define name="OtherStep">
    <choice>
      <ref name="OtherAtomicStep"/>
      <ref name="OtherCompoundStep"/>
    </choice>
  </define>
  <!-- ============================================================ -->
  <define name="Doc">
    <element name="p:doc">
      <ref name="common.attributes"/>
      <zeroOrMore>
        <choice>
          <text/>
          <ref name="_any"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <!-- ============================================================ -->
  <define name="Ignored">
    <ref name="_anyOther"/>
  </define>
  <!-- ============================================================ -->
  <define name="_any.attr">
    <attribute>
      <anyName>
        <except>
          <name>xml:id</name>
          <nsName/>
          <nsName ns=""/>
        </except>
      </anyName>
    </attribute>
  </define>
  <define name="_any.extended.attr">
    <attribute>
      <anyName>
        <except>
          <name>xml:id</name>
        </except>
      </anyName>
    </attribute>
  </define>
  <define name="_anyOther">
    <element>
      <anyName>
        <except>
          <nsName/>
        </except>
      </anyName>
      <zeroOrMore>
        <choice>
          <ref name="_any.extended.attr"/>
          <text/>
          <ref name="_any"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
  <define name="_any">
    <element>
      <anyName/>
      <zeroOrMore>
        <choice>
          <ref name="_any.extended.attr"/>
          <text/>
          <ref name="_any"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>
</grammar>
