tags:

views:

48

answers:

2

This is an XML that I want to get:

<root>
    <A>
        <C>asd</C>
        <D>asd</D>
        <E>asd</E>
    </A>
    <B>
        <C>asd</C>
        <D>asd</D>
        <E>asd</E>
        <F>asd</F>
    </B>
</root>

Here are some more limits:

  • There can be multiple A and B elements, in any order.
  • A and B have exactly the same contents, except that B also may contain element F;
  • C, D, E and F may appear in any order.
  • E can appear multiple times;
  • C and D can appear 0 or 1 times;
  • F must appear exactly 1 time

Is this possible? And on a side note - why is XML schema so awkward in defining such simple scenarios?

A: 

This solves most of your conditions, however the harder one is allowing the any order part. Since you are dealing with complex types your primary usage is the Sequence command. There are others but they do not work for your scenarios either. Also, while this may seem simple from a pure xml perspective it's not from a validation perspective. The main thing to note is that the way this doc is built you would have to put all your <A> records first and all your <B> records second. Here is a link to some of the schema data: w3schools

There may be some much more complicated ways to do what you want but this gives you the basic pattern at least.

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

<xs:complexType name="Avalue">
  <xs:sequence>
    <xs:element minOccurs="0" maxOccurs="1" name="C" type="xs:string"/>
    <xs:element minOccurs="0" maxOccurs="1" name="D" type="xs:string"/>
    <xs:element minOccurs="0" maxOccurs="unbounded" name="E" type="xs:string"/>
  </xs:sequence>
</xs:complexType>


<xs:complexType name="Bvalue">
  <xs:sequence>
    <xs:element minOccurs="0" maxOccurs="1" name="C" type="xs:string"/>
    <xs:element minOccurs="0" maxOccurs="1" name="D" type="xs:string"/>
    <xs:element minOccurs="0" maxOccurs="unbounded" name="E" type="xs:string"/>
    <xs:element minOccurs="1" maxOccurs="1" name="F" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

<xs:element name="root">
  <xs:complexType>
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="A" type="Avalue"/>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="B" type="Bvalue"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

</xs:schema>
Joshua Cauble
yes, but the <xs:sequence> defines a **sequence** - you cannot freely have C, D, E and F tags inside the <A> and <B> tags. That's about as good as it gets with the current XML schema.
marc_s
correct forgot to mention that as well for the sub elements.
Joshua Cauble
A: 

The current XML schema standards probably can't satisfy these requirements. The trouble are the repetitions and the free order of tags appearing.

XML schema currently has basically three ways of structuring XML elements:

  • <xs:all> allows any number of child tags in any order, but each tag can only appears 0 or 1 times

  • <xs:sequence> allows any number of tags, and they can appears any number of times - but as the name implies, only in the defined sequence

  • <xs:choice> allows you to pick one of any number of possible child elements - but only one of x

Given those building blocks, I don't think your requirements can be met. Either you need to restructure your requirements, or you need to find another way to validate those XML files (have you look at Schematron)?

marc_s
The reason I wanted to use XML schema is not for validation, but because many tools provide code-completion for XML files when supplied the schema. I wanted to make writing as easy as possible for the person who would write the XML file. It's sad that the current XML schema cannot support it. I guess I'll have some fixed order of elements then. Still, I can't fathom why they haven't included such an option - it seems so trivial.
Vilx-