Sean Allred
Sean Allred

Reputation: 3658

How can I constrain XML content to other content in the XML (as a reference)?

I want to validate XML if and only if there is a bijection from id=* in method/key and {*} substrings in method/call.

  1. Valid because every {*} corresponds with exactly on id=* and vice-versa.

    <format>
      <call>
        /tags/{1}/top-askers/{2}
      </call>
      <key id="1">
        <name>tag</name>
        <discussion>a tag for the site</discussion>
      </key>
      <key id="2">
        <name>period</name>
      </key>
    </format>
    
  2. Invalid because there is an id=* that has no corresponding {*}.

    <format>
      <call>
        /tags/{1}
      </call>
      <key id="1">
        <name>tag</name>
        <discussion>a tag for the site</discussion>
      </key>
      <key id="2">
        <name>period</name>
      </key>
    </format>
    
  3. Invalid because there is an {*} that has no corresponding id=*.

    <format>
      <call>
        /tags/{1}/top-askers/{2}
      </call>
      <key id="1">
        <name>tag</name>
        <discussion>a tag for the site</discussion>
      </key>
    </format>
    
  4. Ideally, I would also like this to be possible as well, meaning that the contents of {*} could be any of [^}{].

    <format>
      <call>
        /tags/{tag}/top-askers/{2}
      </call>
      <key id="tag">
        <name>tag</name>
        <discussion>a tag for the site</discussion>
      </key>
      <key id="2">
        <name>period</name>
      </key>
    </format>
    

I've looked at the w3schools reference for XML schema, but it doesn't seem to list any such capabilities. It's certainly not a complete reference of the spec, though. Is this possible within XML schema?

Update

@JirkaŠ has provided the following expression which solves (2) (and (4)) but not (3):

for $key in /format/key
  return matches($key/../call,
                 concat("\{", $key/@id, "\}"))

Upvotes: 0

Views: 42

Answers (1)

Jirka Š.
Jirka Š.

Reputation: 3428

IMO, in XSD 1.0 this is not possible. Of course there some basic constraints (xs:unique, xs:key). These are defined using a XPath expression but this expression is only subset of the whole XPath language (see chapter 9.2.5 in http://docstore.mik.ua/orelly/xml/schema/ch09_02.htm). The most restricting in this case is the fact that function calls are not allowed and you probably need some string manipulation function, because "call" element content is a string.

If you can use XSD 1.1 there are some other capabilities how to express more complicated restrictions, especcialy I have "xs:assert" on my mind. I think xpath function might be called in XSD 1.1.

Upvotes: 1

Related Questions