2

I have an XML -Data with the following structure

<Data>
   <Name />
   <Code />
   <Prodprop>
      <key />
      <value />
   </Prodprop>
   <Prodprop>
      <key />
      <value />
   </Prodprop>
   <Tag />
   <Blub />
</Data>

I need an XML Schema for this data , but the tags can appear in any order, but all Prodprop are consecutive. All other elements are needed exactly once or maximal once Therefore the following data is also valid.

 <Data>
       <Code />
       <Name />
       <Tag />
       <Prodprop>
          <key />
          <value />
       </Prodprop>
       <Prodprop>
          <key />
          <value />
       </Prodprop>
    </Data>

This i my (and i know that this is not possible) Schema.

    <xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  <xsd:element name="Data" type="DataType" /> 
  <xsd:complexType name="DataType">
        <xsd:all>
          <xsd:element name="Name" type="xsd:string" />
          <xsd:element name="Code" type="xsd:string" />
          <xsd:element maxOccurs="unbounded" name="Prodprop" type="ProdpropType" />
          <xsd:element name="Tag" type="xsd:string" />
          <xsd:element name="Blub" type="xsd:string" />
        </xsd:all> 
   </xsd:complexType>
    <xsd:complexType name="ProdpropType">
        <xsd:sequence>
          <xsd:element name="key" type="xsd:string" />
          <xsd:element name="value" type="xsd:string" />
        </xsd:sequence> 
       </xsd:complexType> 
  </xsd:schema>

Is there a possibility to make for this szenario a valid xml schema ?

  • 1
    I think what you are trying to do is not possible. But a good idea, close to what you describe, is to wrap Prodprop elements in another element e.g. ProdpropList. With this approach you will have all to Prodprop as a group and whenever they are moved, they are moved as a whole. – Alkis Kalogeris Aug 22 '14 at 10:47
  • I have tried that with a group, but a the all-tag only allows normal elements and no groups – Katharina Kaiser Aug 22 '14 at 10:48

2 Answers2

3

I think what you are trying to do is not possible without using something complicated in xpath.

@C. M. Sperberg-McQueen is right. It is possible, but, if you won't change the requirements to something simpler, you would have to provide all the possible combinations of the order that the tags might have. This solution though is very complicated and troublesome, although perfectly legit.

A good idea, close to what you describe, is to wrap Prodprop elements in another element e.g. ProdpropList. With this approach you will have all Prodprop items as a batch and whenever they are moved, they are moved as a whole.

You can test it online here

Check this: XSD

<xsd:schema attributeFormDefault="unqualified"
    elementFormDefault="qualified" version="1.0"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="Data" type="DataType" />
    <xsd:complexType name="DataType">
        <xsd:all>
            <xsd:element name="Name" type="xsd:string" />
            <xsd:element name="Code" type="xsd:string" />
            <xsd:element name="ProdpropList" type="ProdpropListType" />
            <xsd:element name="Tag" type="xsd:string" />
            <xsd:element name="Blub" type="xsd:string" />
        </xsd:all>
    </xsd:complexType>

    <xsd:complexType name="ProdpropListType">
        <xsd:sequence>
            <xsd:element name="Prodprop" type="ProdpropType"
                maxOccurs="unbounded" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="ProdpropType">
        <xsd:sequence>
            <xsd:element name="key" type="xsd:string" />
            <xsd:element name="value" type="xsd:string" />
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

XML

<Data>
    <Name />
    <Code />
    <ProdpropList>
        <Prodprop>
            <key />
            <value />
        </Prodprop>
        <Prodprop>
            <key />
            <value />
        </Prodprop>
    </ProdpropList>
    <Tag />
    <Blub />
</Data>
Alkis Kalogeris
  • 17,044
  • 15
  • 59
  • 113
  • I already have the data and am creating a schema for the data.. thats the Problem.. . But as i have guessed correctly this is only possible (or managable (as there a a lot more tags) when defining a order of elements and therefore using a sequence... – Katharina Kaiser Aug 25 '14 at 05:53
  • In your question you mentioned `but the tags can appear in any order` so I took that as a given. Of course that's a solution too, but I ruled it out since you specifically mentioned that the tags will not be ordered. Anyway, I'm glad you found a solution. Have fun – Alkis Kalogeris Aug 25 '14 at 07:52
2

If I understand your question correctly, you want the content of the Data element to contain

  • a sequence of zero or more (? or one or more?) Prodprop elements
  • preceded or followed by any number of elements named Name, Code, Tag, Blub, Foo, Bar, Baz, ..., each of which must appear at most once and some of which are optional

The answers which claim that this is impossible are incorrect. The content model you describe is not impossible; it is clearly a regular language and is clearly expressible with an XSD content model. It is certainly possible; it is however extremely inconvenient.

To meet the requirements you state, you will need to create a regular expression for the language (the allowable sequences of children) you describe, and then write that regular expression down as an XSD content model. The task is complicated by XSD's quixotic attempt to keep content models 'simple' by requiring that they be 'deterministic', but you can find descriptions of how to go about in other StackOverflow questions here, here, and here (the last question is about DTDs, not XSD, but the same principles apply).

If you don't want to have a complicated content model, then you can achieve a much simpler one by revising your requirements so they fit your validation technology better.

  • As @alkis has already suggested, you can wrap the Prodprop elements in a wrapper element and then use a simple XSD 1.0 all group.
  • You can specify a required order for children, unless the sequence in which they appear carries some information for your application. (If the sequence carries no information, there is no requirement to allow it to vary.)
Community
  • 1
  • 1
C. M. Sperberg-McQueen
  • 24,596
  • 5
  • 38
  • 65
  • You are right saying that it is possible. The OP can achieve the desired result by specifying all the possible combinations or using some complicated xpath. I will change my answer to include that possibility, but still, it is almost unusable for even 5 tags. Even the addition of one tag would make the xsd unsustainable, that's why I stated that the attempt is impossible. I will try to remember that I have to provide all the possibilities to the OP next time. Thank you for the heads up. +1 – Alkis Kalogeris Aug 24 '14 at 11:40
  • Thank you for this possibility. but as there are a little more tags(at least 20) it would make the xsd a little bit too complex for handling.. Therefore ist much or less impossible. But thanks anyway – Katharina Kaiser Aug 25 '14 at 06:03
  • @KatharinaKaiser, you don't need to apologize to me for solving your problem one way or the other. I do think it's useful to distinguish fairly carefully between "tedious" or "complicated" or "not something I want to do" and "impossible". – C. M. Sperberg-McQueen Aug 25 '14 at 15:04