Is this a valid RELAX NG model? I'm getting " Relax-NG validity error : Invalid sequence in interleave"

187 Views Asked by At

Well, I'm trying to create a RELAX NG schema for PRTG advanced sensor output. Unfortunately the XML specification is a terrible mess IMHO, but I tried anyway.

Basically there are two possible results:

  • Success: There can be a Text element and there will be at least one Result element.
  • Error: There will be an Error element and (an optional?) Text element, too.

So my schema starts like this:

<?xml version="1.0" encoding="utf-8"?>
<!-- RELAX NG specification for PRTG Advanced Sensors -->
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:a="http://relaxng.org/ns/annotation/1.0">
  <start>
    <element name="Prtg">
      <choice>
        <interleave><!-- error -->
          <element name="Error"><ref name="C.Boolean" /></element>
          <element name="Text"><ref name="DT.Message" /></element>
        </interleave>
        <interleave><!-- success -->
          <optional>
            <element name="Text"><ref name="DT.Message" /></element>
          </optional>
          <oneOrMore>
            <element name="Result">
              <interleave>
                <element name="Channel"><text /></element>
                <element name="Value"><text /></element>
                <ref name="PRTG-TagSoup" />
              </interleave>
            </element>
          </oneOrMore>
        </interleave>
      </choice>
    </element>
  </start>
  <!-- ... -->
</grammar>

C.Boolean is basically 0 or 1, and DT.Message is basically <text />. PRTG-TagSoup is a set of all-optional elements that excludes Text, Error, and Result.

I would say it's clear what is an error, and what is success, but xmllint seems to have trouble with that: I get error messages like this:

element Prtg: Relax-NG validity error : Expecting an element Error, got nothing
element Result: Relax-NG validity error : Invalid sequence in interleave
Relax-NG validity error : Extra element Text in interleave
element Prtg: Relax-NG validity error : Element Prtg failed to validate content

A sample input that triggers those messages is:

<?xml version="1.0" encoding="UTF-8"?>
<!--MonitoringOutput v0.2 id=id-16371 (PRTG.xsl v0.0.3)-->
<Prtg>
  <!--status_string=OK-->
  <!--Exit Code: 0-->
  <Text>OK</Text>
  <Result>
    <Channel>wr_wait</Channel>
    <Value>0.938023</Value>
    <!--range: min="0"-->
  </Result>
<!-- ... -->
  <Result>
    <Channel>rd_wait</Channel>
    <Value>0</Value>
    <!--range: min="0"-->
  </Result>
</Prtg>

Somehow my guess is that xmllint seeing the Text element does not know which branch to take. Even if I move the Text element after the last Result element, it does not parse.

Missing Parts

Here are the parts missing, left out to emphasize the core problem (as I see it):

  <define name="C.Boolean">
    <choice datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
      <value type="integer">0</value>
      <value type="integer">1</value>
    </choice>
  </define>

  <define name="DT.Message">
    <data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
          type="string">
      <param name="pattern">".{0,2000}"</param>
    </data>
  </define>

  <define name="PRTG-TagSoup">
    <a:documentation>
      Unordered set of optional elements.
      The actual logic is hard to get from the specification.
    </a:documentation>
    <zeroOrMore>
      <choice>
        <!--- many more... -->
        <element name="CustomUnit"><text /></element>
        <element name="Float"><ref name="C.Boolean" /></element>
        <element name="Warning"><ref name="C.Boolean" /></element>
        <element name="ShowChart"><ref name="C.Boolean" /></element>
        <element name="ShowTable"><ref name="C.Boolean" /></element>
        <element name="LimitErrorMsg"><text /></element>
        <element name="LimitWarningMsg"><text /></element>
        <element name="LimitMode"><ref name="C.Boolean" /></element>
        <element name="ValueLookup"><text /></element>
        <element name="NotifyChanged"><empty /></element>
      </choice>
    </zeroOrMore>
  </define>
1

There are 1 best solutions below

1
mzjn On

There is a mistake in the regular expression used in the DT.Message pattern.

The Jing validator outputs the following error message for your sample XML document and schema:

prtg.xml:6:18: error: character content of element "Text" invalid; must be a string matching the regular expression "".{0,2000}""

If the expression is changed from ".{0,2000}" to .{0,2000}, then the document validates (with both Jing and xmllint).