<?xml version="1.0" encoding="UTF-8"?>

<grammar xmlns="http://relaxng.org/ns/structure/1.0" 
    ns="http://medlane.stanford.edu/ns/marcutl/2.2" 
    xmlns:annotation="http://medlane.stanford.edu/ns/annotation/1.0"
    xmlns:cc="http://www.xml.gr.jp/xmlns/relaxngcc">
    <!--cc:package="info.medlane.marcutl"-->
    
    <start>
        <element name="map">
            <choice>
                <element name="xml">
                    <attribute name="charset">
                        <choice>
                            <value>UTF-8</value>
                            <value>ISO-8859-1</value>
                        </choice>
                    </attribute>
                    <oneOrMore>
                        <element name="record">
                            <optional>
                                <ref name="MARCFormats"/>
                            </optional>
                            <oneOrMore>
                                <element name="field">
                                    <ref name="FieldTag"/>
                                    <oneOrMore>
                                        <element name="match">
                                            <ref name="XMLTransformation"/>
                                        </element>
                                    </oneOrMore>
                                </element>
                            </oneOrMore>
                            <text/>
                        </element>
                    </oneOrMore>
                </element>
                <element name="marc">
                    <attribute name="charset">
                        <choice>
                            <value>ANSEL</value>
                            <value>UTF-8</value>
                        </choice>
                    </attribute>
                    <oneOrMore>
                        <element name="record">
                            <attribute name="type">
                                <choice>
                                    <value>bib</value>
                                    <value>aut</value>
                                    <value>hdg</value>
                                    <value>cif</value>
                                </choice>
                            </attribute>
                            <optional>
                                <ref name="MARCFormats"/>
                            </optional>
                            <optional>
                                <attribute name="source">
                                    <choice>
                                        <value>original</value>
                                        <value>derived</value>
                                    </choice>
                                </attribute>
                            </optional>
                            <optional>
                                <attribute name="status">
                                    <choice>
                                        <value>new</value>
                                        <value>updated</value>
                                        <value>deleted</value>
                                    </choice>
                                </attribute>
                            </optional>
                            <oneOrMore>
                                <element name="field">
                                    <ref name="FieldTag"/>
                                    <oneOrMore>
                                        <element name="match">
                                            <ref name="MARCUpdate"/>
                                        </element>
                                    </oneOrMore>
                                </element>
                            </oneOrMore>
                        </element>
                    </oneOrMore>
                </element>
            </choice>
        </element>
    </start>
    
    <define name="MARCUpdate">
        <optional>
            <attribute name="name"/>
        </optional>
        <ref name="MatchPattern"/>
        <oneOrMore>
            <ref name="MARCResult"/>
        </oneOrMore>
        <zeroOrMore>
            <element name="output">
                <choice>
                    <group>
                        <attribute name="format">
                            <value>display</value>
                        </attribute>
                        <optional>
                            <attribute name="level">
                                <choice>
                                    <value>record</value>
                                    <value>field</value>
                                    <value>subfield</value>
                                    <value>record id</value>
                                </choice>
                            </attribute>
                        </optional>
                    </group>
                    <group>
                        <attribute name="format">
                            <value>marc</value>
                        </attribute>
                        <optional>
                            <attribute name="level">
                                <value>record</value>
                            </attribute>
                        </optional>
                    </group>
                </choice>
                <zeroOrMore>
                    <element name="filename">
                        <text/>
                    </element>
                </zeroOrMore>
                <zeroOrMore>
                    <element name="note">
                        <optional>
                            <attribute name="position">
                                <choice>
                                    <value>after</value>
                                    <value>before</value>
                                </choice>
                            </attribute>
                        </optional>
                        <text/>
                    </element>
                </zeroOrMore>
            </element>
        </zeroOrMore>
    </define>
    
    <define name="XMLTransformation">
        <attribute name="name"/>
        <ref name="MatchPattern"/>
        <oneOrMore>
            <element name="result">
                <choice>
                    <element name="dtd">
                        <attribute name="location">
                            <choice>
                                <value>SYSTEM</value>
                                <value>PUBLIC</value>
                            </choice>
                        </attribute>
                        <text/>
                    </element>
                    <element name="root">
                        <attribute name="name"/>
                        <optional>
                            <element name="namespace">
                                <text/>
                            </element>
                            <zeroOrMore>
                                <element name="namespace">
                                    <attribute name="id"/>
                                    <text/>
                                </element>
                            </zeroOrMore>
                        </optional>
                        <zeroOrMore>
                            <element name="attribute">
                                <optional>
                                    <attribute name="namespaceID"/>
                                </optional>
                                <attribute name="name"/>
                                <text/>
                            </element>
                        </zeroOrMore>
                        <empty/>
                    </element>
                    <element name="element">
                        <attribute name="parent"/>
                        <attribute name="name"/>
                        <optional>
                            <attribute name="namespaceID"/>
                        </optional>
                        <choice>
                            <ref name="PatternPath"/>
                            <ref name="Concatenation"/>
                            <text/>
                            <group>
                                <optional>
                                    <attribute name="value">
                                        <value>empty</value>
                                    </attribute>
                                </optional>
                                <empty/>
                            </group>
                        </choice>
                    </element>
                    <element name="attribute">
                        <optional>
                            <attribute name="namespaceID"/>
                        </optional>
                        <attribute name="name"/>
                        <choice>
                            <ref name="PatternPath"/>
                            <text/>
                        </choice>
                    </element>
                </choice>
            </element>
        </oneOrMore>
        <zeroOrMore>
            <element name="output">
                <choice>
                    <group>
                        <attribute name="format">
                            <value>XML</value>
                        </attribute>
                        <optional>
                            <attribute name="level">
                                <value>record</value>
                            </attribute>
                        </optional>
                    </group>
                    <group>
                        <attribute name="format">
                            <value>display</value>
                        </attribute>
                        <optional>
                            <attribute name="level">
                                <value>record id</value>
                            </attribute>
                        </optional>
                    </group>
                </choice>
                <zeroOrMore>
                    <element name="filename">
                        <text/>
                    </element>
                </zeroOrMore>
                <zeroOrMore>
                    <element name="note">
                        <optional>
                            <attribute name="position">
                                <choice>
                                    <value>after</value>
                                    <value>before</value>
                                </choice>
                            </attribute>
                        </optional>
                        <text/>
                    </element>
                </zeroOrMore>
            </element>
        </zeroOrMore>
    </define>
    
    <define name="MatchPattern">
        <element name="pattern">
            <optional>
                <attribute name="syntax">
                    <value>regexp</value>
                </attribute>
            </optional>
            <choice>
                <group>
                    <ref name="Occurrence"/>
                    <optional>
                        <ref name="Indicators"/>
                    </optional>
                </group>
                <group>
                    <optional>
                        <ref name="Indicators"/>
                    </optional>
                    <ref name="FieldContent"/>
                </group>
            </choice>
        </element>
    </define>
    
    <define name="FieldContent">
        <choice>
            <element name="value">
                <text/>
            </element>
            <ref name="Data"/>
            <ref name="Subfield"/>
            <ref name="Group"/>
        </choice>
    </define>
    
    <define name="Group">
        <element name="group">
            <attribute name="syntax">
                <choice>
                    <value>and</value>
                    <value>or</value>
                </choice>
            </attribute>
            <oneOrMore>
                <ref name="GroupContent"/>
            </oneOrMore>
            <optional>
                <oneOrMore>
                    <ref name="Group"/>
                </oneOrMore>
            </optional>
        </element>
    </define>
    
    <define name="GroupContent">
        <interleave>
            <zeroOrMore>
                <ref name="Byte"/>
            </zeroOrMore>
            <zeroOrMore>
                <ref name="Substring"/>
            </zeroOrMore>
            <zeroOrMore>
                <ref name="Subfield"/>
            </zeroOrMore>
            <zeroOrMore>
                <ref name="Field"/>
            </zeroOrMore>
        </interleave>
    </define>
    
    <define name="Field">
        <element name="field">
            <ref name="FieldTag"/>
            <optional>
                <ref name="Indicators"/>
            </optional>
            <choice>
                <group>
                    <optional>
                        <ref name="Occurrence"/>
                    </optional>
                    <choice>
                        <element name="value">
                            <text/>
                        </element>
                        <ref name="Byte"/>
                        <ref name="Substring"/>
                        <empty/>
                        <!--<ref name="Data"/>-->
                    </choice>
                </group>
                <oneOrMore>
                    <ref name="Subfield"/>
                </oneOrMore>
            </choice>
        </element>
    </define>
    
    <define name="Subfield">
        <element name="subfield">
            <optional>
                <attribute name="name">
                    <text/>
                </attribute>
            </optional>
            <optional>
                <ref name="Occurrence"/>
            </optional>
            <choice>
                <text/>
                <ref name="Data"/>
            </choice>
        </element>
    </define>
    
    <define name="Byte">
        <element name="byte">
            <attribute name="position">
                <text/>
            </attribute>
            <optional>
                <attribute name="value"/>
            </optional>
            <empty/>
        </element>
    </define>
    
    <define name="Substring">
        <element name="substring">
            <attribute name="from">
                <choice>
                    <text/>
                    <value>start</value>
                </choice>
            </attribute>
            <attribute name="to">
                <choice>
                    <text/>
                    <value>end</value>
                </choice>
            </attribute>
            <choice>
                <text/>
                <empty/>
            </choice>
        </element>
    </define>
    
    <define name="Data">
        <choice>
            <ref name="Byte"/>
            <ref name="Substring"/>
            <empty/>
        </choice>
    </define>
    
    <define name="Indicators">
        <element name="indicators">
            <choice>
                <group>
                    <ref name="FirstIndicator"/>
                    <optional>
                        <ref name="SecondIndicator"/>
                    </optional>
                </group>
                <group>
                    <optional>
                        <ref name="FirstIndicator"/>
                    </optional>
                    <ref name="SecondIndicator"/>
                </group>
            </choice>
            <empty/>
        </element>
    </define>
    
    <define name="FirstIndicator">
        <attribute name="first">
            <text/> <!-- datatype: char or chars separated by whitespace -->
        </attribute>
    </define>
    
    <define name="SecondIndicator">
        <attribute name="second">
            <text/> <!-- datatype: char or chars separated by whitespace -->
        </attribute>
    </define>
    
    <define name="MARCFormats">
        <attribute name="format">
            <choice>
                <value>mono</value>
                <value>ser</value>
                <value>cfile</value>
                <value>carto</value>
                <value>audio</value>
                <value>video</value>
                <value>mixed</value>
                <value>person</value>
                <value>org</value>
                <value>event</value>
                <value>title</value>
                <value>topic</value>
                <value>lang</value>
                <value>chrono</value>
                <value>geog</value>
                <value>type</value>
                <value>q-topic</value>
                <value>q-lang</value>
                <value>q-geog</value>
                <value>q-chrono</value>
                <value>q-type</value>
                <value>person</value>
                <value>org</value>
                <value>title</value>
                <value>event</value>
                <value>other</value>
                <value>classif</value>
                <text/>
            </choice>
        </attribute>
    </define>
    
    <define name="ValueChoice">
        <choice>
            <ref name="PatternPath"/>
            <ref name="Concatenation"/>
            <text/>
        </choice>
    </define>
    
    <define name="Concatenation">
        <element name="concat">
            <optional>
                <attribute name="trim"/>
                <attribute name="from">
                    <choice>
                        <value>start</value>
                        <value>end</value>
                    </choice>
                </attribute>
            </optional>
            <choice>
                <group>
                    <attribute name="pattern"/>
                    <empty/>
                </group>
                <group>
                    <element name="source">
                        <optional>
                            <ref name="PatternPath"/>
                        </optional>    
                        <text/>
                    </element>
                    <oneOrMore>
                        <element name="source">
                            <optional>
                                <ref name="PatternPath"/>
                            </optional>    
                            <text/>
                        </element>
                    </oneOrMore>
                </group>
            </choice>
        </element>
    </define>
    
    <define name="MARCResult">
        <element name="result">
            <choice>
                <group>
                    <attribute name="action">
                        <value>burst</value>
                    </attribute>
                    <ref name="PatternPath"/>
                    <optional>
                        <attribute name="target">
                            <value>bib</value>
                        </attribute>
                    </optional>
                    <oneOrMore>
                        <element name="case">
                            <choice>
                                <attribute name="value"/>
                                <attribute name="else">
                                    <value>other</value>
                                </attribute>
                            </choice>
                            <oneOrMore>
                                <element name="field">
                                    <ref name="FieldTag"/>
                                    <optional>
                                        <ref name="Indicators"/>
                                    </optional>
                                    <oneOrMore>
                                        <element name="subfield">
                                            <attribute name="name">
                                                <text/>
                                            </attribute>
                                            <choice>
                                                <text/>
                                                <ref name="Concatenation"/>
                                                <group>
                                                    <ref name="PatternPath"/>
                                                    <empty/>
                                                </group>
                                            </choice>
                                        </element>
                                    </oneOrMore>
                                </element>
                            </oneOrMore>
                        </element>
                    </oneOrMore>
                </group>
                <group>
                    <attribute name="action">
                        <value>add</value>
                    </attribute>
                    <optional>
                        <attribute name="target">
                            <value>bib</value>
                        </attribute>
                    </optional>
                    <oneOrMore>
                        <element name="field">
                            <ref name="FieldTag"/>
                            <optional>
                                <ref name="Indicators"/>
                            </optional>
                            <oneOrMore>
                                <element name="subfield">
                                    <attribute name="name">
                                        <text/>
                                    </attribute>
                                    <ref name="ValueChoice"/>
                                </element>
                            </oneOrMore>
                        </element>
                    </oneOrMore>
                </group>
                <group>
                    <attribute name="action">
                        <value>replace</value>
                    </attribute>
                    <oneOrMore>
                        <element name="source">
                            <ref name="PatternPath"/>
                        </element>
                        <element name="with">
                            <ref name="ValueChoice"/>
                        </element>
                    </oneOrMore>
                </group>
                <group>
                    <attribute name="action">
                        <value>delete</value>
                    </attribute>
                    <ref name="PatternPath"/>
                </group>
                <group>
                    <attribute name="action">
                        <value>move</value>
                    </attribute>
                    <ref name="MoveOrCopy"/>
                </group>
                <group>
                    <attribute name="action">
                        <value>copy</value>
                    </attribute>
                    <ref name="MoveOrCopy"/>
                </group>
                <group>
                    <attribute name="action">
                        <value>reorder</value>
                    </attribute>
                    <oneOrMore>
                        <element name="source">
                            <ref name="PatternPath"/>
                        </element>
                        <element name="target">
                            <attribute name="position">
                                <choice>
                                    <value>first</value>
                                    <value>last</value>
                                    <text/> <!-- data type int -->
                                </choice>
                            </attribute>
                        </element>
                    </oneOrMore>
                </group>
                <group>
                    <attribute name="action">
                        <value>custom</value>
                    </attribute>
                    <attribute name="class"/>
                    <optional>
                        <attribute name="target">
                            <value>bib</value>
                        </attribute>
                    </optional>
                    <zeroOrMore>
                        <element name="param">
                            <text/>
                        </element>
                    </zeroOrMore>
                </group>
                <group>
                    <attribute name="action">
                        <value>suppress</value>
                    </attribute>
                    <empty/>
                </group>
            </choice>
        </element>
    </define>
    
    <annotation:markup>
        <p>MoveOrCopy moves or copies a field into a new field.  The difference
        is that 'move' deletes what was moved while 'copy' leaves a copy there.
        The 'from' pattern should point to the lowest possible position in the
        field to be moved or copied so the selected field is clear. If you want
        to keep something in the same field (tag), use the 'replace' action.</p>
    </annotation:markup>
    
    <define name="MoveOrCopy">
        <optional>
            <attribute name="target">
                <value>bib</value>
            </attribute>
        </optional>
        <oneOrMore>
            <element name="from">
                <ref name="PatternPath"/>
                <empty/>
            </element>
            <element name="to">
                <ref name="FieldTag"/>
                <optional>
                    <ref name="Indicators"/>
                </optional>
                <oneOrMore>
                    <element name="subfield">
                        <optional>
                            <attribute name="name">
                                <text/>
                            </attribute>
                        </optional>
                        <ref name="PatternPath"/>
                    </element>
                </oneOrMore>
            </element>
        </oneOrMore>
    </define>

    <define name="PatternPath">
        <attribute name="pattern">
            <text/> <!-- create datatype: QBEPattern -->
        </attribute>
    </define>
    
    <define name="Occurrence">
        <attribute name="occurrence">
            <text/><!-- datatype as int -->
        </attribute>
    </define>
    
    <define name="FieldTag">
        <attribute name="tag">
            <text/><!-- create datatype: 3 char string -->
        </attribute>
    </define>
    
</grammar>