Question

I am writing a RelaxNG Compact schema for an XML file where the contents of the <wrap> elements must be exactly one of:

<wrap><a/></wrap>
<wrap><b/></wrap>
<wrap><a/><b/></wrap>
<wrap><b/><a/></wrap>

In English, either <a/> or <b/> are allowed once each, or both in either order, but one of them is required to be present.

Is there a better (more compact) definition of WrapElement than the following?

grammar {
  start = 
    element wrap { WrapElement }

  WrapElement =
    (
      element a {empty}, 
      element b {empty}?
    )|(
      element a {empty},
      element b {empty}?
    )
}

The following is close. It's certainly more terse, it matches all the permitted variations, and disallows the elements from occurring more than once. However, it also incorrectly allows an empty <wrap/> element:

grammar {
  start = 
    element wrap { WrapElement }

  WrapElement =
    element a {empty}?
    & element b {empty}?
}
Was it helpful?

Solution

The following works for me:

grammar {
  start = 
    element wrap { (a|b)|(a&b) }

  a = element a {empty}
  b = element b {empty}
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top