2

I am brand new to creating schema and almost brand new to creating XML. I am trying to develop a simple integer-based type (although I would settle for a string-based type) that restricts values to -1 and then even integers through 254.

So far I have figured out:

   <xs:simpleType name="toffset">
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="-1"/>
      <xs:maxInclusive value="254"/>
    </xs:restriction>

That code of course doesn't deal with restricting values >-1 to even integers. I considered creating an enumeration but that seems unwieldy for so many values. How can I achieve the desired restriction?

kjhughes
  • 106,133
  • 27
  • 181
  • 240
TomT
  • 199
  • 1
  • 1
  • 11
  • I really appreciate all of the great answers. Any one of them would have gotten the job done and the first two seem like they were probably the cleanest solutions for 1.0 and 1.1 (respectively). Ultimately I flagged Michael's answer as the endorsed answer because my tools (I work in Delphi XE7) don't seem to meaningfully support 1.1. However, as soon as it does, I will prefer using assertions -- so Lexicore's answer will eventually be my preferred approach. Thanks again to all -- I learned a lot from your answers. – TomT Jan 07 '15 at 22:04

3 Answers3

5

Certainly the XSD 1.1 mechanism using assertions is cleaner. In XSD 1.0 the only way to restrict integers in this way is using the pattern facet, as @kjhughes suggests. However, you can use patterns on integers, they don't apply only to strings.

I think I would do it like this:

<xs:simpleType name="toffset">
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="-1"/>
      <xs:maxInclusive value="254"/>
      <xs:pattern value="-.*|.*[02468]"/>
    </xs:restriction>
</xs:simpleType>

Here most of the heavy lifting is done by the min/max constraints, and the pattern is used only to restrict the value so that it either (a) starts with a "-" sign, or (b) ends with an even digit. There's no need for the pattern to repeat constraints that apply anyway, e.g. that the other characters are digits.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • 1
    Ahh, never considered that regex patterns would work with integers. +1 to you and +10 to whomever improved the XSD 1.0 Rec's regularity in this delightful manner! – kjhughes Jan 07 '15 at 13:14
3

You do it with regular expressions:

  <xs:simpleType name="loanNumberType">
    <xs:restriction base="xs:string">
      <xs:pattern value="-1"/>
      <xs:pattern value="[02468]"/>
      <xs:pattern value="[1-9][02468]"/>
      <xs:pattern value="1[0-9][02468]"/>
      <xs:pattern value="2[0-4][02468]"/>
      <xs:pattern value="25[024]"/>
    </xs:restriction>
  </xs:simpleType>
kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • I'd say it is a *funny* idea. What I dislaike a bit us that you have `xs:string` as base type (probably necessary for `xs:pattern`) This goes a bit against the nature of the target type and will be misrepresenten in many tools. – lexicore Jan 07 '15 at 07:27
  • I did laugh at myself a bit when I figured that regex's could capture even/odd properties. :-) Michael's answer builds on this but retains the natural numeric typing better. – kjhughes Jan 07 '15 at 13:21
3

In XSD 1.0 you can define enumerations as you propose or user patterns as Kenneth suggests. From my PoV enumerations are better as they don't obfuscate the underlying type. The disadvantage is too many entries, that's true. But I think that's lesser evil.

In XSD 1.1. you could do something like

<xs:simpleType name="toffset">
  <xs:restriction base="xs:integer">
    <xs:assertion test="$value = -1 or ($value <= 254 and ($value mod 2) = 0)"/>
  </xs:restriction>
</xs:simpleType>

I'm not quite sure about the syntax in @test, but you get the idea.

Links:

Community
  • 1
  • 1
lexicore
  • 42,748
  • 17
  • 132
  • 221
  • At some point (1K entries; 1M entries; infinite entries?), the evilness of enumeration will surpass that of using strings rather than integers if XSD 1.1 can't be used. :-) But, yeah, I agree with the sentiment (+1). Check out Michael Kay's cool answer, though. – kjhughes Jan 07 '15 at 13:18
  • @kjhughes Yep, saw it. The best choice for XSD 1.0. – lexicore Jan 07 '15 at 13:19