0

I have an XML document (minimum reproducible example) that looks like this:

<root start="baz">
    <child name="foo">...</child>
    <child name="bar">...</child>
    <child name="baz">...</child>
</root>

I would like my schema to enforce the fact that the start attribute on the root element must reference an existing child node with that name. If there is no child node with a name attribute with that value, validation should fail. In other words the above should validate, but this should not:

<root start="baz">
    <child name="foo">...</child>
    <child name="bar">...</child>
</root>

What is a good way to do this? Do I really need to use an assert with a suitable XPath expression or is there a more natural way to express this in XSD? Thanks.

PS: assume start is a required attribute and the child name attributes are marked unique in the appropriate scope.

Thomas
  • 3,321
  • 1
  • 21
  • 44

1 Answers1

1

You're looking for xsd:key/xsd:keyref. See:

XML Schema key/keyref - how to use them?

Probably somethig like:

<xsd:key name="root-child-name"> 
  <xsd:selector xpath="root/child"/> 
  <xsd:field xpath="@name"/> 
</xsd:key> 
<xsd:keyref name="root-start" refer="root-child-name"> 
  <xsd:selector xpath="root"/> 
  <xsd:field xpath="@start"/> 
</xsd:keyref> 
Community
  • 1
  • 1
lexicore
  • 42,748
  • 17
  • 132
  • 221
  • I had to put `xpath="."` in the keyref for this to work for me, how would I do it otherwise? If `root` is in fact the root element I can't put the keyref any higher up in the document tree, so the xpath can't work, and apparently slashes aren't supported in the selector. – Thomas Nov 22 '16 at 09:51