user2172305
user2172305

Reputation: 11

XSD questions: abstracts and polymorphic documents

I'm working a project (assigned to me by a "pointy-haired manager"), and I've run into two things that are stumping me. I have read a number of articles both here and on w3schools - still confused. I think I need a practical example.

I am including a significantly pared-down & obfuscated version of the XSD that I am desperately trying to get to "validate".

Problem #1 has to do (I think) with using 'abstract/substitutionGroup' - not very clear to me. What I need is for the 3 variant groups to have the same node-name (in this example "zzzResult").

Problem #2 has to do with polymorphism. I need to add special "markers" to indicate the begin/end of some external operation (using XPath & JS) plus a special node of data BASED on the main document attribute named "hash" (or rather the value of its enums).

Can someone provide a 'corrected' version that will work?


<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<!-- payload containers -->

  <xsd:element name="thePayload" type="xsd:string"/>

  <xsd:element name="md5">
    <xsd:simpleType>
      <xsd:restriction base="xsd:hexBinary">
        <xsd:pattern value="[0-9A-Fa-f]{32}"/>
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

  <xsd:element name="sha1">
    <xsd:simpleType>
      <xsd:restriction base="xsd:hexBinary">
        <xsd:pattern value="[0-9A-Fa-f]{40}"/>
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>

<!-- markers -->

  <xsd:element name="zzzBegin"><xsd:complexType/></xsd:element>
  <xsd:element name="zzzEnd"><xsd:complexType/></xsd:element>

<!-- constructs -->

  <xsd:element name="theHeading">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="thePayload" maxOccurs="8"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

  <xsd:element name="theDetails">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="thePayload" maxOccurs="64"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

<!-- groups -->

  <xsd:group name="_none">
    <xsd:sequence>
      <xsd:element ref="theHeading"/>
      <xsd:element ref="theDetails"/>
    </xsd:sequence>
  </xsd:group>

  <xsd:group name="_md5">
    <xsd:sequence>
      <xsd:element ref="zzzBegin"/>
      <xsd:element ref="theHeading"/>
      <xsd:element ref="theDetails"/>
      <xsd:element ref="zzzEnd"/>
    <!-- problem #1) [abstract?] ambiguous name -->
      <xsd:element name="zzzResult">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element ref="md5"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:group>

  <xsd:group name="_sha1">
    <xsd:sequence>
      <xsd:element ref="zzzBegin"/>
      <xsd:element ref="theHeading"/>
      <xsd:element ref="theDetails"/>
      <xsd:element ref="zzzEnd"/>
    <!-- problem #1) [abstract?] ambiguous name -->
      <xsd:element name="zzzResult">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element ref="sha1"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:group>

  <xsd:group name="_both">
    <xsd:sequence>
      <xsd:element ref="zzzBegin"/>
      <xsd:element ref="theHeading"/>
      <xsd:element ref="theDetails"/>
      <xsd:element ref="zzzEnd"/>
    <!-- problem #1) [abstract?] ambiguous name -->
      <xsd:element name="zzzResult">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element ref="md5"/>
            <xsd:element ref="sha1"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:group>

<!-- XML DOCUMENT -->

  <xsd:element name="theDocument">
    <xsd:complexType>

 <!-- problem #2) [polymorphic?] choose based on enum-value of attrib "hash" -->
      <xsd:choice>
        <xsd:group ref="_none"/>
        <xsd:group ref="_md5"/>
        <xsd:group ref="_sha1"/>
        <xsd:group ref="_both"/>
      </xsd:choice>

      <xsd:attribute name="hash" default="none">
        <xsd:simpleType>
          <xsd:restriction base="xsd:NMTOKEN">
            <xsd:enumeration value="none"/>
            <xsd:enumeration value="md5"/>
            <xsd:enumeration value="sha1"/>
            <xsd:enumeration value="both"/>
          </xsd:restriction>
        </xsd:simpleType>
      </xsd:attribute>

    </xsd:complexType>
  </xsd:element>

Here's what I need the variant forms to look like:


<theDocument hash="none">
  <theHeading>
    <thePayload>some data here (occurs 1:8)</thePayload>
  </theHeading>
  <theDetails>
    <thePayload>more data here (occurs 1:64)</thePayload>
  </theDetails>
</theDocument>

<theDocument hash="md5">
 <zzzBegin/>
  <theHeading>
    <thePayload>some data here (occurs 1:8)</thePayload>
  </theHeading>
  <theDetails>
    <thePayload>more data here (occurs 1:64)</thePayload>
  </theDetails>
 <zzzEnd/>
  <zzzResult>
    <md5>0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a</md5>
  </zzzResult>
</theDocument>

<theDocument hash="sha1">
 <zzzBegin/>
  <theHeading>
    <thePayload>some data here (occurs 1:8)</thePayload>
  </theHeading>
  <theDetails>
    <thePayload>more data here (occurs 1:64)</thePayload>
  </theDetails>
 <zzzEnd/>
  <zzzResult>
    <sha1>3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e</sha1>
  </zzzResult>
</theDocument>

<theDocument hash="both">
 <zzzBegin/>
  <theHeading>
    <thePayload>some data here (occurs 1:8)</thePayload>
  </theHeading>
  <theDetails>
    <thePayload>more data here (occurs 1:64)</thePayload>
  </theDetails>
 <zzzEnd/>
  <zzzResult>
    <md5>0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a</md5>
    <sha1>3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e</sha1>
  </zzzResult>
</theDocument>

Upvotes: 1

Views: 242

Answers (1)

Petru Gardea
Petru Gardea

Reputation: 21658

There is no way to correct your XSD 1.0 while maintaining the given set of tags and constraints because of the Unique Particle Attribution limitation.

XSD 1.1 - the most recent version of the XSD spec - provides all the mechanisms you need to enforce your model's constraints the way you want.

If XSD 1.1 is not an option, Schematron markup on top of XSD 1.0 would allow you to relax some of the constraints in your current XSD which would allow one to reconfigure your content models to avoid the UPA issue, yet maintain the constraints. Specifically, you can start by having one zzzResult where md5 and sha1 are both present and optional; then you'll end up with only two groups (as per your current approach), _none and something else.

In the spirit of SO, I would kindly ask you to consider the above as leads to go back and try new things considering your options; and if you're still getting into issues, come back here with new details.

Upvotes: 1

Related Questions