Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. XML / XSL
  4. XSD Unique Implementation and XPath

XSD Unique Implementation and XPath

Scheduled Pinned Locked Moved XML / XSL
xmlhelptutorialquestion
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Skippums
    wrote on last edited by
    #1

    Firstly, if anyone could send me a link that explains everything that is allowed in XSD xpath expressions, I would be very grateful. I have searched for hours, and still have no idea what subset of xpath is allowed for either the selector or the field nodes. Great thanks to anyone who knows where I can find some documentation on this feature of xsd. On to my problem... I am attempting to have an element, "parent", that contains a key attribute called "key". Every such element may have 0 or more child elements, called "Child", such that they contain a keyref attribute called "key" as well. I am wondering if there is a way to enforce through the XSD that the value of "key" for the child elements cannot be equivalent to the value of "key" for the parent node. So, for example: <!-- XSD File -->

    <xsd:element name="Example" type="ExampleType">
    <xsd:key name="ParentKey">
    <xsd:selector xpath="Parent"/>
    <xsd:field xpath="@key" />
    </xsd:key>
    <xsd:keyref name="ChildKeyRef" refer="ParentKey">
    <xsd:selector xpath="Parent/Child"/>
    <xsd:field xpath="@key" />
    </xsd:keyref>
    </xsd:element>

    <xsd:complexType name="ExampleType">
    xsd:sequence
    <xsd:element name="Parent" type="ParentType" maxOccurs="unbounded">
    <!-- This unique portion is where I need the help. It almost works in that it prevents me from
    giving a child element the parent's key, but it also has the unfortunate side effect of not
    allowing me to have duplicate key references in the child elements. How can this be done? -->
    <xsd:unique name="UniqueKeyRef">
    <xsd:selector xpath=".|Child"/>
    <xsd:field xpath="@key" />
    </xsd:unique>
    </xsd:element>
    </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="ParentType">
    <xsd:attribute name="key" type="xsd:String" use="required"/>
    xsd:sequence
    <xsd:element name="Child" type="ChildType" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="ChildType">
    <xsd:attribute name="key" type="xsd:String" use="required"/>
    </xsd:complexType>

    <-- XML File -->

    <Example>
    <Parent key="A">
    <Child key="B"/>

    C S 2 Replies Last reply
    0
    • S Skippums

      Firstly, if anyone could send me a link that explains everything that is allowed in XSD xpath expressions, I would be very grateful. I have searched for hours, and still have no idea what subset of xpath is allowed for either the selector or the field nodes. Great thanks to anyone who knows where I can find some documentation on this feature of xsd. On to my problem... I am attempting to have an element, "parent", that contains a key attribute called "key". Every such element may have 0 or more child elements, called "Child", such that they contain a keyref attribute called "key" as well. I am wondering if there is a way to enforce through the XSD that the value of "key" for the child elements cannot be equivalent to the value of "key" for the parent node. So, for example: <!-- XSD File -->

      <xsd:element name="Example" type="ExampleType">
      <xsd:key name="ParentKey">
      <xsd:selector xpath="Parent"/>
      <xsd:field xpath="@key" />
      </xsd:key>
      <xsd:keyref name="ChildKeyRef" refer="ParentKey">
      <xsd:selector xpath="Parent/Child"/>
      <xsd:field xpath="@key" />
      </xsd:keyref>
      </xsd:element>

      <xsd:complexType name="ExampleType">
      xsd:sequence
      <xsd:element name="Parent" type="ParentType" maxOccurs="unbounded">
      <!-- This unique portion is where I need the help. It almost works in that it prevents me from
      giving a child element the parent's key, but it also has the unfortunate side effect of not
      allowing me to have duplicate key references in the child elements. How can this be done? -->
      <xsd:unique name="UniqueKeyRef">
      <xsd:selector xpath=".|Child"/>
      <xsd:field xpath="@key" />
      </xsd:unique>
      </xsd:element>
      </xsd:sequence>
      </xsd:complexType>

      <xsd:complexType name="ParentType">
      <xsd:attribute name="key" type="xsd:String" use="required"/>
      xsd:sequence
      <xsd:element name="Child" type="ChildType" minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
      </xsd:complexType>

      <xsd:complexType name="ChildType">
      <xsd:attribute name="key" type="xsd:String" use="required"/>
      </xsd:complexType>

      <-- XML File -->

      <Example>
      <Parent key="A">
      <Child key="B"/>

      C Offline
      C Offline
      Christian Graus
      wrote on last edited by
      #2

      Not sure if this answers your question ( I didn't read it all ), but I've always used this[^] when I need to do XSLT/XPath stuff.

      Christian Graus Driven to the arms of OSX by Vista. Read my blog to find out how I've worked around bugs in Microsoft tools and frameworks.

      1 Reply Last reply
      0
      • S Skippums

        Firstly, if anyone could send me a link that explains everything that is allowed in XSD xpath expressions, I would be very grateful. I have searched for hours, and still have no idea what subset of xpath is allowed for either the selector or the field nodes. Great thanks to anyone who knows where I can find some documentation on this feature of xsd. On to my problem... I am attempting to have an element, "parent", that contains a key attribute called "key". Every such element may have 0 or more child elements, called "Child", such that they contain a keyref attribute called "key" as well. I am wondering if there is a way to enforce through the XSD that the value of "key" for the child elements cannot be equivalent to the value of "key" for the parent node. So, for example: <!-- XSD File -->

        <xsd:element name="Example" type="ExampleType">
        <xsd:key name="ParentKey">
        <xsd:selector xpath="Parent"/>
        <xsd:field xpath="@key" />
        </xsd:key>
        <xsd:keyref name="ChildKeyRef" refer="ParentKey">
        <xsd:selector xpath="Parent/Child"/>
        <xsd:field xpath="@key" />
        </xsd:keyref>
        </xsd:element>

        <xsd:complexType name="ExampleType">
        xsd:sequence
        <xsd:element name="Parent" type="ParentType" maxOccurs="unbounded">
        <!-- This unique portion is where I need the help. It almost works in that it prevents me from
        giving a child element the parent's key, but it also has the unfortunate side effect of not
        allowing me to have duplicate key references in the child elements. How can this be done? -->
        <xsd:unique name="UniqueKeyRef">
        <xsd:selector xpath=".|Child"/>
        <xsd:field xpath="@key" />
        </xsd:unique>
        </xsd:element>
        </xsd:sequence>
        </xsd:complexType>

        <xsd:complexType name="ParentType">
        <xsd:attribute name="key" type="xsd:String" use="required"/>
        xsd:sequence
        <xsd:element name="Child" type="ChildType" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
        </xsd:complexType>

        <xsd:complexType name="ChildType">
        <xsd:attribute name="key" type="xsd:String" use="required"/>
        </xsd:complexType>

        <-- XML File -->

        <Example>
        <Parent key="A">
        <Child key="B"/>

        S Offline
        S Offline
        Stuart Dootson
        wrote on last edited by
        #3

        The Essential XML Quick Reference[^] is an excellent (and free) XML (+ XSD + XPath + XSLT) reference. On page 349, it defines the available XPath selectors (I'd copy them here, but it disallows copying - grrrr). However, I don't think you can do what you want with the 'unique' relation. The correctness 'uniqueness' set would be '..|.' using the Child element as the context node. But you can't do that with XML Schemas. Using the Parent as context node, there's no way to define the uniqueness set, I don't think, as there are n sets, where n==number of Child nodes. However - using Schematron[^], you can validate this rule using this Schema:

        <schema xmlns="http://www.ascc.net/xml/schematron" >
        <pattern name="Check CHild/Parent keys">
        <rule context="Child">
        <assert test="@key!=../@key">Child key should differ from Parent key.</assert>
        <report test="@name">Child key should differ from Parent key.</report>
        </rule>
        </pattern>
        </schema>

        This should be used in addition to a schema describing the basic structure of the XML. Using xmllint (which comes with libxml2), I can confirm that this Schematron schema meets your requirements. XML files can be validated against Schematron schemas using an XSLT processor, so even if your XML parser doesn't have Schematron support, you can still use Schematron.

        Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

        S 1 Reply Last reply
        0
        • S Stuart Dootson

          The Essential XML Quick Reference[^] is an excellent (and free) XML (+ XSD + XPath + XSLT) reference. On page 349, it defines the available XPath selectors (I'd copy them here, but it disallows copying - grrrr). However, I don't think you can do what you want with the 'unique' relation. The correctness 'uniqueness' set would be '..|.' using the Child element as the context node. But you can't do that with XML Schemas. Using the Parent as context node, there's no way to define the uniqueness set, I don't think, as there are n sets, where n==number of Child nodes. However - using Schematron[^], you can validate this rule using this Schema:

          <schema xmlns="http://www.ascc.net/xml/schematron" >
          <pattern name="Check CHild/Parent keys">
          <rule context="Child">
          <assert test="@key!=../@key">Child key should differ from Parent key.</assert>
          <report test="@name">Child key should differ from Parent key.</report>
          </rule>
          </pattern>
          </schema>

          This should be used in addition to a schema describing the basic structure of the XML. Using xmllint (which comes with libxml2), I can confirm that this Schematron schema meets your requirements. XML files can be validated against Schematron schemas using an XSLT processor, so even if your XML parser doesn't have Schematron support, you can still use Schematron.

          Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

          S Offline
          S Offline
          Skippums
          wrote on last edited by
          #4

          Yeah, that is what I was afraid of... I know I could do it using XSD 1.1 or, as you suggested, Schematron, but validating against either of those options isn't well supported (at least as far as I can tell) in Java or C. I actually tried what you suggested with the parent element, saw it wasn't supported, and figured that there must just be some other well-hidden way to go about it. I don't want to have a second definition file, so embedded Schematron may be the answer right now (if I can figure out how to validate against it), or I could just wait until next April when the XSD 1.1 specification is finalized. Anyway, thank you very much for the help!

          Sounds like somebody's got a case of the Mondays -Jeff

          S 1 Reply Last reply
          0
          • S Skippums

            Yeah, that is what I was afraid of... I know I could do it using XSD 1.1 or, as you suggested, Schematron, but validating against either of those options isn't well supported (at least as far as I can tell) in Java or C. I actually tried what you suggested with the parent element, saw it wasn't supported, and figured that there must just be some other well-hidden way to go about it. I don't want to have a second definition file, so embedded Schematron may be the answer right now (if I can figure out how to validate against it), or I could just wait until next April when the XSD 1.1 specification is finalized. Anyway, thank you very much for the help!

            Sounds like somebody's got a case of the Mondays -Jeff

            S Offline
            S Offline
            Stuart Dootson
            wrote on last edited by
            #5

            Schematron is supported by libxml2, so (therefore) is accessible to C or C++ or anything else that exposes that part of libxml2 through a binding. The Schematron website describes the steps needed to perform Schaematron validation:

            xslt -stylesheet iso_dsdl_include.xsl theSchema.sch > theSchema1.sch
            xslt -stylesheet iso_abstract_expand.xsl theSchema1.sch > theSchema2.sch
            xslt -stylesheet iso_svrl_for_xsltn.xsl theSchema2.sch > theSchema.xsl
            xslt -stylesheet theSchema.xsl myDocument.xml > myResult.xml

            Basically, generate an XSLT file from your Schematron schema (the first three steps). Then process the input XML file using your XSLT processor and the generated XSLT file to output something that tells you if the XML is valid per the Schematron schema.

            Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups