0

I would like to use conditions in my XSD schema for my XML document.

I used restrictions but it's not quite powerful.

Here is an example of what I did so far:

<xs:element name="Matricule">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="valeur">
                    <xs:simpleType>
                        <xs:restriction base="xs:integer">
                            <xs:minInclusive value="0"></xs:minInclusive>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
                <xs:element type="xs:string" name="backgroundcolor"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>

This example works fine but I check just if the value is greater than 0. But I would like to verify if the value is an Integer AND if the value is empty.

Maybe something like that:

If (value > 0 AND value < 100 AND value = '')

I found on Google a subject who calls about assertion, so I read the document and I did that

<xs:element name="Matricule">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="valeur">
                    <xs:simpleType>
                        <xs:restriction base="xs:integer">
                            <xs:minInclusive value="0"></xs:minInclusive>
                            **<xs:assertion test="($value mod 10) = 0"/>**
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>
                <xs:element type="xs:string" name="backgroundcolor"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>

But it doesn't work, I always have an error.

Exemple 1 with value :

<racine>
  <row>
    <Matricule>
      <valeur>55</valeur>
      <backgroundcolor></backgroundcolor>
    </Matricule>
  </row>
</racine> 

Exemple 2 without value :

<racine>
  <row>
    <Matricule>
      <valeur></valeur>
      <backgroundcolor></backgroundcolor>
    </Matricule>
  </row>
</racine>

These two examples need to be correct but this one no :

<racine>
  <row>
    <Matricule>
      <valeur>gfd</valeur>
      <backgroundcolor></backgroundcolor>
    </Matricule>
  </row>
</racine>
Stoufiler
  • 175
  • 1
  • 2
  • 13
  • What do you mean, "the value is empty"? What kind of XML is it that you want to accept and the restriction you put wouldn't accept? Assertions are for XSD 1.1, which isn't widely supported. You probably don't want it and it is unlikely to help you even if it was supported. – kumesana Aug 31 '17 at 07:58
  • Ok i had modify my post, and i hope you better understand is. In fact, i need to use xml validator to check all my file – Stoufiler Aug 31 '17 at 08:05

2 Answers2

1

I suspect you mean that the value must EITHER be a number between 0 and 100, OR be an empty string. If that's the case, you're getting muddled between AND and OR.

An empty string is not a valid instance of xs:integer, so you can't define this type as a restriction of xs:integer (because a restriction can only define a value space that is a subset of the base value space).

There are two common ways to define a simple type where the value must either be an X, or be empty:

  1. Define a union type whose member types are X, and a type derived from xs:string whose only permitted value is ""

  2. Define a list type whose item type is X, and whose maxOccurs is 1.

(In this case X is a restriction of xs:integer with minInclusive=0, maxInclusive=100).

Personally I prefer (2): it works better if you are using schema-aware queries and transformations. But if you're only using the schema for validation, it makes no difference.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • thanks for comment, i will think about that, but because i use python script, maybe i can check all the values of my xml file with the library ElementTree. What do you think about it ? – Stoufiler Aug 31 '17 at 08:55
  • I don't know Python or ElementTree. – Michael Kay Aug 31 '17 at 08:57
  • Ok, no problem, i will try to make a function, because my XML file contains more than 1500000 lines – Stoufiler Aug 31 '17 at 08:58
  • Hello again, i've got some problems with my XML file and my XSD, I need to verify if the value is between 0 and 100 or empty. I search on Google how works list and union but I don't understand very much, can you explain me how it works please regards – Stoufiler Aug 31 '17 at 12:40
1

If you need to accept empty elements, then their content is not of type integer, as an empty string does not represent a number.

You will have to settle on type xs:string and just restrict it with a pattern that accept either integers or empty string.

This would work:

<xs:simpleType>
  <xs:restriction base="xs:string">
    <xs:pattern value="[0-9]*"/>
  </xs:restriction>
</xs:simpleType>

As it says you accept, a digit from 0 to 9, zero or more consecutive times.

If you need it also inferior to 100, I'll let you find a pattern that enforces this additional condition.

kumesana
  • 2,495
  • 1
  • 9
  • 10
  • ok i tried, your answer but it doesn't work too, i have this error `res.xml:1029800: element valeur: Schemas validity error : Element 'valeur': '55' is not a valid value of the local atomic type.` – Stoufiler Aug 31 '17 at 09:00
  • I think you need to double check that you're really validating the XML you think with the XSD you think. I tried to validate your XML sample with my solution, and it works. – kumesana Aug 31 '17 at 09:10
  • OHHH, I'm very sorry, I forgotten to put the start at the end of the pattern – Stoufiler Aug 31 '17 at 09:12
  • I'm sorry to ask another thing but now I would like to check a date or nothing, I use this pattern but he didn't work `` I test it and it works on regex101.com – Stoufiler Aug 31 '17 at 09:47
  • While I like the simplicity of my solution with integers, it doesn't work on something as complicated as dates. For this you'd need to follow @michael-kay 's solutions. For information, ^ and $ serve no purpose in XSD pattern validation, and are therefore not accepted. More exactly they're taken literally, which is not what you want. You just need to not put them. But really, a pattern here is not the solution you want. – kumesana Aug 31 '17 at 10:07
  • thanks, now I will learn about xsd list and ask him if i can't do something – Stoufiler Aug 31 '17 at 10:12