0
votes

Here is my XML file. This file has to be validated against the following conditions

  1. The child -> child1 -> parentData -> name element should be present in parent -> parent* -> name
  2. The total length (4 + 3 = 7 in this case) of the children of a particular parent (Parent 2) should be equal to the length element of that element
  3. If the part 4-6 of Parent2 is used by child1, no other child should use the same part of Parent2 and many more...

Please help me with how should I validate this XML file. I tried generating a XSD file from Visual Studio and was able to implement a unique constraint for the parent and child names.

<sample>
    <parent>
      <parent1>
        <name>Parent 1</name>
        <length>10</length>
      </parent1>
      <parent2>
        <name>Parent 2</name>
        <length>7</length>
      </parent2>
      <parent3>
        <name>Parent 3</name>
        <length>20</length>
      </parent3>
    </parent>
    <child>
      <child1>
        <length>3</length>
        <parentData>
          <name>Parent 2</name>
          <start>4</start>
          <stop>6</stop>
        </parentData>
      </child1>
      <child2>
        <length>4</length>
        <parentData>
          <name>Parent 2</name>
          <start>0</start>
          <stop>3</stop>
        </parentData>
      </child2>
    </child>
  </sample>
1

1 Answers

1
votes

First note that the validity of an element in XSD only depends on the recursive content of that element, never on its siblings, parents, or ancestors. This tells you that a rule defining constraints between <parent> and <child> elements (I'll use angle brackets for element names to avoid confusion with axis names) has to go on the <sample> element: that's the element that's invalid if the constraint is invalid.

Also note that use of element names like child1 and child2 isn't making your life easier. If two elements represent the same real-world entity and have the same internal structure and rules, then give them the same name.

The child -> child1 -> parentData -> name element should be present in parent -> parent* -> name

That's a key/keyref defined on <sample>. The key has selector = parent//name, field = .; the keyref has selector = child//parentData/name, field = ..

>     The total length (4 + 3 = 7 in this case) of the children of a particular parent (Parent 2) should be equal to the length element of
> that element

That needs assertions, and therefore XSD 1.1. Again it's an assertion defined on <sample>, and it's going to be something like every $p in parent/* satisfies $p/length = sum(child/*[parentData/name = $p/name]/length).

If the part 4-6 of Parent2 is used by child1, no other child should use the same part of Parent2 and many more...

That one's much harder and I'm not going to attempt it. Again it's an assertion on <sample>. As a hint, if you assume that start<end has already been validated, then I think you can express the constraint that two children $c1 and $c2 don't overlap as ($c1/end < $c2/start or $c2/end < @c1/start). So the constraint will take the form every $c1 in XXX, $c2 in XXX satisfies ($c1 is $c2 or $c1/end < $c2/start or $c2/end < @c1/start)