Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

xml - Define an XSD element which can be a dateTime or empty with an attribute

My question is almost exactly the same as this one, but for a xs:dateTime type rather than a user defined element.

An element in my XML (which I do not create) can look like:

<parent>
    ...
    <start>2012-01-01T00:00:00.000</start>
    <end>2013-01-01T00:00:00.000</end>
    ...
</parent>

-or-

<parent>
    ...
    <start reference="a string" />
    <end reference="a string" />
    ...
</parent>

In other words, within the parent element, the "start" and "end" fields can contain either a xs:dateTime value, or will be empty but have a "reference" attribute (either field might be one or the other within the parent, they're not necessarily both a reference or both a dateTime). I've tried all sorts of ways to represent this in an XSD, but have not found a solution. The closest I've come is (excerpted from a much larger XSD):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="DateOrRef">
    <xs:simpleContent>
<!--      <xs:extension base="xs:dateTime"> This does not validate-->
      <xs:extension base="xs:string">
        <xs:attribute type="xs:string" name="reference" use="optional"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="parent">
    <xs:sequence>
        <xs:element minOccurs="0" name="start" type="DateOrRef" />
        <xs:element minOccurs="0" name="end" type="DateOrRef" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

which does validate, but does not restrict the node contents to be an xs:dateTime value. If I change the extension base type to a xs:dateTime instead of xs:string as in the commented out line, the empty elements will no longer validate because the dateTime type is not allowed to be empty.

How could I structure the XSD to validate these fields as xs:dateTime instead of xs:string?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

1 You can declare the element nillable (as suggested by Ben).

2 You can declare a simple type which is a union of xs:dateTime and the empty string. This is easiest to follow if we build it up in stages. First, declare a named simple type whose sole value is the empty string:

<xs:simpleType name="empty-string">
  <xs:restriction base="xs:string">
    <xs:enumeration value=""/>
  </xs:restriction>
</xs:simpleType>

Then declare a union type whose members are xs:dateTime and empty-string:

<xs:simpleType name="dateTime-or-nothing">
  <xs:union memberTypes="xs:dateTime empty-string"/>
</xs:simpleType>

Then use dateTime-or-nothing as the basis for your extension step:

<xs:complexType name="DateOrRef">
  <xs:simpleContent>
    <xs:extension base="dateTime-or-nothing">
      <xs:attribute type="xs:string" 
                    name="reference" 
                    use="optional"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>

If the reference attribute should occur if and only if the element has no content, then you'll need an XSD 1.1 assertion to that effect (or an ancillary Schematron schema, or ad-hoc validation code at the application layer). XSD content models make it easy to say you must have either a dateTime or a reference, but only if each of those options is represented by a child element.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...