XML schema restriction to values of another element

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • mruedy
    New Member
    • May 2010
    • 3

    XML schema restriction to values of another element

    I would like to know if it is possible to write an XML Schema restriction that binds to values of another element.

    For example I have XML
    Code:
    <people>
        <family name="Smith">
            <origin>England</origin>
        </family>
        <family name="Jain">
            <origin>India</origin>
        </family>
        <family name="DelSol">
            <origin>Spain</origin>
        </family>
        <person>
             <Given>Mary</Given>
             <Family>Smith</Family>
        </person>
        <person>
             <Given>Jorege</Given>
             <Family>DelSol</Family>
        </person>
        <person>
             <Given>Sundeep</Given>
             <Family>Jain</Family>
        </person>
        <person>
             <Given>John</Given>
             <Family>Farley</Family>
        </person>
    </people>
    In the following XML Schema I would like to restrict the Family value of a person to one of the name attributes of the family elements. This should complain on the last person as the Family name was not listed as a family element.

    Is it possible to do so?

    Thanks
    Mark

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="people">
        <xs:complexType>
          <xs:sequence>
            <xs:element maxOccurs="unbounded" name="family">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="origin" type="xs:string" />
                </xs:sequence>
                <xs:attribute name="name" type="xs:string" use="required" />
              </xs:complexType>
            </xs:element>
            <xs:element maxOccurs="unbounded" name="person">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="Given" type="xs:string" />
                  <xs:element name="Family" type="xs:string" />
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    Last edited by Dormilich; May 5 '10, 10:02 PM. Reason: Please use [code] tags when posting code
  • rski
    Recognized Expert Contributor
    • Dec 2006
    • 700

    #2
    I'm afraid not in XML Schema. But you can define it in Schematron

    Comment

    • jkmyoung
      Recognized Expert Top Contributor
      • Mar 2006
      • 2057

      #3
      Yes you can, assuming no 2 family names are the same.

      Put this at the end of your people node:
      Code:
      <xs:keyref name="familyNameRef" refer="familyName">
      	<xs:selector xpath="person"/>
      	<xs:field xpath="Family"/>
      </xs:keyref>
      <xs:key name="familyName">
      	<xs:selector xpath="family"/>
      	<xs:field xpath="@name"/>
      </xs:key>
      Your validator should throw an error like:
      cvc-identity-constraint.4.3: Key 'familyNameRef' with value 'Farley' not found for identity constraint of element 'people'.

      Comment

      • mruedy
        New Member
        • May 2010
        • 3

        #4
        Originally posted by jkmyoung
        Yes you can, assuming no 2 family names are the same.

        Put this at the end of your people node:
        Code:
        <xs:keyref name="familyNameRef" refer="familyName">
        	<xs:selector xpath="person"/>
        	<xs:field xpath="Family"/>
        </xs:keyref>
        <xs:key name="familyName">
        	<xs:selector xpath="family"/>
        	<xs:field xpath="@name"/>
        </xs:key>
        Your validator should throw an error like:
        cvc-identity-constraint.4.3: Key 'familyNameRef' with value 'Farley' not found for identity constraint of element 'people'.
        jkmyoung,

        With your snippet, I get this

        ~/family > xmllint --noout --schema people.xsd people.xml
        Unimplemented block at xmlschemas.c:55 88
        Unimplemented block at xmlschemas.c:55 88
        people.xml validates
        ~/family >


        I put the block just before the </xs:element> (end tag) for people. Is that the correct location? I am using:

        ~/family > xmllint --version
        xmllint: using libxml version 20616
        compiled with: DTDValid FTP HTTP HTML C14N Catalog XPath XPointer XInclude Iconv Unicode Regexps Automata Schemas
        ~/family >

        Thanks

        Comment

        • jkmyoung
          Recognized Expert Top Contributor
          • Mar 2006
          • 2057

          #5
          I didn't know you were using xmllint. XML Schema support in libxml2 is quite incomplete.

          I've heard there is a newer version of xmllint, but am not sure. Try:
          http://www.xmlsoft.org/ to find an updated version.

          Comment

          • mruedy
            New Member
            • May 2010
            • 3

            #6
            Originally posted by jkmyoung
            I didn't know you were using xmllint. XML Schema support in libxml2 is quite incomplete.

            I've heard there is a newer version of xmllint, but am not sure. Try:
            http://www.xmlsoft.org/ to find an updated version.
            Is there a non-network based (local executable) validator that will work with this?

            Comment

            Working...