2

I've the following XML

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<props>
<id>someId</id>
<file_size>
    <size>123</size>
    <unit>MB</unit>
</file_size>
<file_size>
    <size>123</size>
    <unit>MB</unit>
</file_size>
</props>

And the corresponding XSD:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified" elementFormDefault="qualified">
<xs:element name="props">
    <xs:complexType>
        <xs:sequence>
            <xs:element type="xs:string" name="id" />
            <xs:element name="file_size" maxOccurs="unbounded" minOccurs="0">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element type="xs:int" name="size" />
                        <xs:element type="xs:string" name="unit" />
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

My goal is to allow unordered elements and i saw ALL indicator solution

but, how can i maintain the file_size behavior? I found some solutions to put:

<file_size>
    <size>123</size>
    <size>125</size>
    <unit>MB</unit>
    <unit>TB</unit>
</file_size>

but i need to have several file_size (with one size and one unit).

To resume, all of the children of props to be in any order but have any number of file_size elements.

How can i handle this?

JMarques
  • 3,044
  • 4
  • 34
  • 55

2 Answers2

3

This is quite an awkward requirement for XML Schema 1.0. It would be easy to do either of

  • exactly one each of id and file_size, in either order (using an all)
<xs:all>
    <xs:element type="xs:string" name="id" />
    <xs:element name="file_size">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="xs:int" name="size" />
                <xs:element type="xs:string" name="unit" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:all>
  • any number of id and any number of file_size elements, in any order (using a repeating choice)
<xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:element type="xs:string" name="id" />
    <xs:element name="file_size">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="xs:int" name="size" />
                <xs:element type="xs:string" name="unit" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:choice>

but to satisfy your specific requirement of any number of file_size elements but exactly one id is rather clumsy. The clearest way I can see to do it would be to move the file_size definition up to the top level and then ref in zero-or-more occurrences at both possible places:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified" elementFormDefault="qualified">

<xs:element name="file_size">
    <xs:complexType>
        <xs:sequence>
            <xs:element type="xs:int" name="size" />
            <xs:element type="xs:string" name="unit" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:element name="props">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="file_size" minOccurs="0" maxOccurs="unbounded" />
            <xs:element type="xs:string" name="id" />
            <xs:element ref="file_size" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>
</xs:element>
Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
  • Unfortunately, that solution doesn't work because i've more than one element (imagine not one but several id's - I only put one id in XML and XSD to simplify this). I'm pretty sure that the solution, if there's any, is using the but i don't know how to put the with multi-ocorrences – JMarques Jul 15 '14 at 17:39
  • @JMarques no, the elements under an `all` cannot occur more than once. The closest you could get would be to allow all the other elements with an `all`, followed by zero or more (or one-or-more) `file_size` elements, but there's no easy way to intersperse multiple `file_size` elements in between the others unless you're prepared to allow more than one of each of the other elements too. – Ian Roberts Jul 15 '14 at 18:29
  • 1
    @JMarques if you can use XML Schema 1.1 then you could go the `xs:choice` route but then restrict the other elements to a single occurrence using an XPath assertion. – Ian Roberts Jul 15 '14 at 19:45
  • I was hopping for a cleaner solution but thanks =) What i have to implement it's a kind of trick anyway =) – JMarques Jul 15 '14 at 21:35
0

You are looking in the right place. You only need to make one small change to your schema:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    attributeFormDefault="unqualified" elementFormDefault="qualified">
    <xs:element name="props">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="xs:string" name="id" />
                <xs:element name="file_size" maxOccurs="unbounded" minOccurs="0">
                    <xs:complexType>
                        <xs:all>
                            <xs:element type="xs:int" name="size" />
                            <xs:element type="xs:string" name="unit" />
                        </xs:all>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>
Nic Gibson
  • 7,051
  • 4
  • 31
  • 40
  • It won't work, i need to have the XML elements unorder :( In this case the id and file_sizer must be in order (sequence). – JMarques Jul 15 '14 at 14:01
  • OK. So the `file_size` and `id` must be in that order but the other elements can be in any order? Your question says you want several file_size elements. Am I right to think that you want all of the children of `props` to be in any order but have any number of `file_size` elements? – Nic Gibson Jul 15 '14 at 14:05
  • "all of the children of props to be in any order but have any number of file_size elements" Yes, it's exactly that. Probably i wasn't clear enought but i said that . Just in case, i edit the question to be more clear =) Do you know a solution, please? – JMarques Jul 15 '14 at 16:50