3

I've been trying out the following. I want to create an XSD for an XML where certain elements are allowed to appear only once and need to be valid, and elements from other namespaces are allowed anywhere, and have no schema they have to validate with.

XML that should be allowed:

<ns:bookstore>
  <ns:books>
    <ns:book1 />
    <other:magazine1 />
    <ns:book2 />
    <ns:book3 />
    <otherns:newspaper1  />
    <ns:book4 />
  </ns:books>
</ns:bookstore>

book1,2,3 and 4 can only appear once in the XML and need to be validated, elements in other namespaces then ns: should be allowed without being validated. For this I use an xs:any with processContents lax in my XSD:

 <xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="ns">

<xs:element name="bookstore">
   <xs:complexType>
      <xs:sequence >
        <xs:element name ="book1" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book2" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book3" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book4" type="xs:string" maxOccurs="1"/>
        <xs:any processContents="lax" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
       </xs:sequence>
    </xs:complexType>
</xs:element>

In this solution, the elements in other namespaces can only appear after the sequence, and not in between the obligatory elements. The ideal solution (but I know it's not allowed in XSD) is to change my xs:sequence in an xs:all (but xs:any is not allowed in xs:all)

I know there are questions like this, but none of the answers there are clear to me. Can someone offer me a workaround for this problem?

I've also tried the following:

 <xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="ns">

<xs:element name="bookstore">
   <xs:complexType>
      <xs:choice maxOccurs="unbounded" >
        <xs:element name ="book1" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book2" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book3" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book4" type="xs:string" maxOccurs="1"/>
        <xs:any processContents="lax" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
       </xs:choice>
    </xs:complexType>
</xs:element>

Because the unbounded occurs of the choice, any element from the choice can occur as many times as they want at any position. But here book1, 2, 3 and 4 can occur multiple times, with is not allowed in my use case.

Does anybody have another idea that might help me? Thanks in advance!!

P.S.: The types of my books are in fact complexTypes and all different from eachother, this is just a simplified version of the XML.

EDIT:

This isn't allowed either in my XSD:

   <xs:element name="bookstore">
   <xs:complexType>
      <xs:sequence >
        <xs:element name ="book1" type="xs:string" maxOccurs="1"/>
        <xs:any processContents="lax" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name ="book2" type="xs:string" maxOccurs="1"/>
        <xs:any processContents="lax" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name ="book3" type="xs:string" maxOccurs="1"/>
        <xs:element name ="book4" type="xs:string" maxOccurs="1"/>
        <xs:any processContents="lax" namespace="##other" minOccurs="0"    maxOccurs="unbounded"/>
       </xs:sequence>
    </xs:complexType>
</xs:element>
Tcanarchy
  • 760
  • 1
  • 8
  • 20

1 Answers1

1

In XSD 1.1 you can do this very easily by defining an open content model:

<xs:complexType ...>
  <xs:openContent mode="interleave">
    <xs:any namespace=.../>
  </xs:openContent>
  ... regular content model ...
</xs:complexType>

There's no easy way to do it in 1.0; you just have to put an optional wildcard in every possible position.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • "you just have to put an optional wildcard in every possible position." Can you give an example of that? Are more xs:any allowed inside one sequence? – Tcanarchy Aug 07 '14 at 13:47
  • 1
    I mean something like `sequence (x *? y *? z *?)` where *? is an xs:any wildcard with minOccurs=0, and x, y, z are element declarations. – Michael Kay Aug 07 '14 at 13:52
  • Doesn't that violate the Unique Particle Attribution? I remember trying this. – Tcanarchy Aug 07 '14 at 13:55
  • 1
    In XSD 1.0 you have to make sure that the wildcard doesn't allow the namespace that's used for the named elements, so there is no ambiguity. – Michael Kay Aug 07 '14 at 20:46
  • I've added an edit to my post, to show you what I think you meant by your previous comment. However, this is not allowed according to my XSD. Am I misunderstanding you? Thanks for your help, I will accept your answer after this. – Tcanarchy Aug 08 '14 at 07:26
  • 1
    The schema you supplied looks valid to me. I've checked it with Saxon, Xerces, and libxml. I've also checked that it allows other-namespace elements in the specified positions. What schema processor are you using, and what error are you getting? Also, what are the values of targetNamespace and elementFormDefault in your xs:schema element? – Michael Kay Aug 08 '14 at 08:28
  • I'm using Eclipse Web Tools Platform plug-in to validate my XSD. This is the error I received: cos-nonambig: WC[##other:""] and WC[##other:""] (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles. My targetNamespace is empty and elementFormDefault is qualified. – Tcanarchy Aug 08 '14 at 08:37
  • I would expect Eclipse to use Xerces so I'm puzzled. It would help to post the full schema. – Michael Kay Aug 08 '14 at 15:36
  • So am I... Publishing the entire schema is not an option I'm afraid. I've worked around the problem by changing my XSLT so that wildcards only appear after the declared elements. I will accept your answer because obviously it should work as you say. Thank you for your time and patience. – Tcanarchy Aug 11 '14 at 06:39