Compact RelaxNG circuit for both / both elements in any order

I am writing a RelaxNG Compact schema for an XML file, where the content 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/> allowed once or both in any order, but it is required that one of them 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. This, of course, is more eloquent, it corresponds to all allowed options and does not allow elements to occur more than once. However, it also incorrectly resolves an empty <wrap/> element:

 grammar { start = element wrap { WrapElement } WrapElement = element a {empty}? & element b {empty}? } 
+4
source share
1 answer

The following works for me:

 grammar { start = element wrap { (a|b)|(a&b) } a = element a {empty} b = element b {empty} } 
+5
source

Source: https://habr.com/ru/post/1496668/


All Articles