4

I have a document type similar to the following:

<foo>
  <settings>
    <!-- Must be present; in any order -->
    <time>abc</time>
    <validRun>true</validRun>
    <!-- Tool may add whatever ones it wants -->
    <somethingNotCheckedFor>abc</somethingNotCheckedFor>
  </settings>
</foo>

The following document is semantically the same as the preceding document:

<foo>
  <settings>
    <validRun>true</validRun>
    <somethingNotCheckedFor>abc</somethingNotCheckedFor>
    <time>abc</time>
  </settings>
</foo>

but the following is invalid:

<foo>
  <settings>
    <validRun>true</validRun>
    <somethingNotCheckedFor>abc</somethingNotCheckedFor>
    <!-- Error: Required element "time" not present -->
  </settings>
</foo>

I tried something like the following but this does not work because <xs:all> is not allowed to contain <xs:any>:

<xs:all>
  <xs:element name="time" />
  <xs:element name="validRun" />
  <xs:any />
</xs:all>

Is there some means to do this in W3C Schema?

Rookie Programmer Aravind
  • 11,952
  • 23
  • 81
  • 114
Billy ONeal
  • 104,103
  • 58
  • 317
  • 552

2 Answers2

3
  1. You can use XSD 1.1, which does allow wildcards to appear within all-groups.

  2. If your required elements are in a namespace and you can require that elements added by the generator not be in that namespace, then you can write a content model using choices and sequences that recognizes the language you want (if you really have only two required elements, it's not too hard; if you have three or four it becomes cumbersome, and if you have more than five you don't want to do this way without a compiler). What you need is a content model like this:

    <xs:sequence>
      <xs:any namespace="##other" 
              minOccurs="0" 
              maxOccurs="unbounded"/>
      <xs:choice>
        <xs:sequence>
          <xs:element ref="time"/>
          <xs:any namespace="##other" 
                  minOccurs="0" 
                  maxOccurs="unbounded"/>
          <xs:element ref="validRun"/>
        </xs:sequence>
        <xs:sequence>
          <xs:element ref="validRun"/>
          <xs:any namespace="##other" 
                  minOccurs="0" 
                  maxOccurs="unbounded"/>
          <xs:element ref="time"/>
        </xs:sequence>
      </xs:choice>
      <xs:any namespace="##other" 
              minOccurs="0" 
              maxOccurs="unbounded"/>
    </xs:sequence>
    
  3. You can declare settings with a content model containing just a lax repeating wildcard, and check at the application level (1) that it contains both time and validRun and (2) that those two children are valid.

Of these, I think XSD 1.1 is likely to produce the most satisfactory results, if you can use an XSD 1.1 validator. At the moment, both Xerces J and Saxon-EE support XSD 1.1; most other XSD tools do not.

C. M. Sperberg-McQueen
  • 24,596
  • 5
  • 38
  • 65
  • Note that, besides the namespace restriction, this solution allows more than one unspecified element as a child of the `` element. If you have only two required elements, then it won't be too much work to make a `` for all combinations. If the elements inserted by the generator must be in the same namespace, then you could use a wrapper element (for example ``) that contains the generated element(s), because `` matches also for ` – jasso Dec 10 '12 at 21:19
2

I guess you know how to use <any/> element!! ie, you cannot take <any/> element by literal meaning but you have to declare possible list of elements ..

I guess this will explain the usage of <any/> as well as solution to your problem!! :))

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="foo" type="foo"/>
  <xs:complexType name="foo">
    <xs:sequence>
      <xs:element name="settings" type="settings"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="settings">
      <xs:sequence>
        <xs:any minOccurs="1" maxOccurs="1"/>
        <xs:any minOccurs="1" maxOccurs="1"/>
        <xs:any minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
  </xs:complexType>
  <xs:element name="somethingNotCheckedFor" type="xs:string"/>
  <xs:element name="time" type="xs:string" />
  <xs:element name="validRun" type="xs:boolean" />
  <xs:element name="somethingNotCheckedForTWO" type="xs:string"/>
</xs:schema>

The above schema doesn't allow any other elements than declared ones .. And it doesn't allow them to be repeated also no restriction on order!!

You can declare all possible elements in place of <somethingNotCheckedFor/> !! like I have declared <somethingNotCheckedForTWO/> as well.

Below listed XML samples are succeed with validation! :
1.

<?xml version="1.0" encoding="utf-8"?>
<foo>
  <settings>
    <time>abc</time>
    <somethingNotCheckedForTWO>abc</somethingNotCheckedForTWO>
    <validRun>true</validRun>
  </settings>
</foo>

2.

<?xml version="1.0" encoding="utf-8"?>
<foo>
  <settings>
    <time>abc</time>
    <validRun>true</validRun>
    <somethingNotCheckedForTWO>abc</somethingNotCheckedForTWO>
  </settings>
</foo>

3.

<?xml version="1.0" encoding="utf-8"?>
<foo>
  <settings>
    <somethingNotCheckedFor>abc</somethingNotCheckedFor>
    <time>abc</time>
    <validRun>true</validRun>
  </settings>
</foo>
Rookie Programmer Aravind
  • 11,952
  • 23
  • 81
  • 114
  • "You can declare all possible elements in place of !! like I have declared as well." <-- No, I can't do that. According to this file format (which I was attempting to retrofit with a schema), the generator tool is allowed to add whatever extra elements in there it wants. I can't define them all in the schema. – Billy ONeal Dec 04 '12 at 18:25
  • @BillyONeal, that shouldn't be the reason for your downvote! By you comment I understand that you don't know how to use `` element .. Though you were unaware of it, I explained you in the first line on my answer .. go through it carefully.. !! YOU CANNOT EXPECT SCHEMA TO ACCEPT ANY ELEMENT BLINDLY!! it has to be declared in one or the other way !! that is the basics of XSD, that one should know his XML.. otherwise what is the use of having SCHEMA?? – Rookie Programmer Aravind Dec 05 '12 at 04:25
  • First thing you didn't read the answer carefully .. and u downvoted coz you didn't get what you want! I am disappointed with the attitude you have towards fellow members who are trying to help you!! – Rookie Programmer Aravind Dec 05 '12 at 04:26
  • Well. Coming to the point, your requirement is impossible to achieve with XSD. – Rookie Programmer Aravind Dec 05 '12 at 04:54
  • I downvoted because your answer does not answer my question, which clearly indicates an element which is not explicitly named in the schema. (Otherwise, why would `any` be required at all?) As for "what is the point of schema"; verifying that a set of required elements are present is useful. In the real schema, this problematic bit is part of a larger document which does not cause problems for Schema; and validating that would still be useful too. I think you're right that this requirement is unenforceable due to the Unique Particle Attribution Rule. :( – Billy ONeal Dec 05 '12 at 06:04
  • In that case, I would suggest you to go with schematron ! or through programming languages like C#, or java whichever is hosting this XSD validation .. (in detail: list all the elements/attributes that u want to be validated along with their XPath, Load XML using XML DOM object and verify if the XPath returns null, if yes then validation fails).. – Rookie Programmer Aravind Dec 05 '12 at 06:45
  • I agree that it's not recommended and also it's bit complicated chunk of code, but all that matters is achieving requirement in possible ways.. btw SCHEMATRON is a better suggestion .. its been years since Schematron got introduced so it's been in good usage now a days .. You will get to see schematron libraries (ex for C#, Java) I guess it wouldn't be much difficult .. all that is not possible with XSD is possible bet with schematron! – Rookie Programmer Aravind Dec 05 '12 at 06:49
  • If you don't wanna try schematron then you still have XML DOM and XPATH to validate required tags only! Since you don't have enforcement of sequence, it makes your task much easier. – Rookie Programmer Aravind Dec 05 '12 at 07:01
  • 1
    @InfantProgrammer'Aravind' "you cannot take `` element by literal meaning but you have to declare possible list of elements" That is not correct. If the `processContents` attribute is not `strict` then the elements don't need to be defined in this, or in any referred, schema document. So, unlike what you claimed, you actually can expect schema to accept any element blindly. – jasso Dec 10 '12 at 21:08
  • W3C's schema recommendation tells more than a sample code http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#process_contents For a sample code here is one old answer by me http://stackoverflow.com/a/6164197/420851 and here is another one with the effect of `processContents=lax` explained http://zvon.org/xxl/XMLSchemaTutorial/Output/ser_import_st1.html – jasso Dec 11 '12 at 16:26