在RelaxNG中将元素定义为非空

时间:2011-06-01 03:14:57

标签: xml relaxng

我已经开始使用RelaxNG来指定XML消息模式,并使用PHP DOMDocument来验证和解析传入的消息,但是无法弄清楚如何定义文本节点以使其不能为空。示例模式:

<?xml version="1.0"?>
<element name="amhAPI" xmlns="http://relaxng.org/ns/structure/1.0">
    <element name="auth">
        <element name="validateUser">
            <element name="username">
                <text/>
            </element>

            <element name="password">
                <text/>
            </element>
        </element>
    </element>
</element>

但是,DOMDocument::relaxNGValidate方法正在验证下面的消息是正确的(因为relaxng matches any arbitrary string [包括空的text模式)并且相当于):

<?xml version="1.0"?>
<amhAPI>
    <auth>
        <validateUser>
            <username/>
            <password/>
        </validateUser>
    </auth>
</amhAPI>

因此,我必须为不应该为空的字段添加一堆检查和验证,如果验证器将它们识别为非空元素,则可以将其删除。

有没有办法强制非空文本?

3 个答案:

答案 0 :(得分:10)

前面的解决方案并不总是很有效。如果将minLength构面设置为“1”,则接受一个单个空白字符(或一个换行符)。如果您使用模式.*[\S]+.*,则无法插入任何换行符,但这仅适用于“用户名”和“密码”(请参阅​​上面的示例)。

正则表达式是正确的方法,但是要将元素定义为非空,更好的解决方案(对我来说)是通用模式:(.|\n|\r)*\S(.|\n|\r)*,因此您也可以在任何地方使用换行符。

答案 1 :(得分:4)

如果您的RELAX NG验证器支持XSD数据类型(大部分都是),那么您可以使用正则表达式来优化文本内容的约束:

<?xml version="1.0"?>
<element name="amhAPI" xmlns="http://relaxng.org/ns/structure/1.0"
  datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <element name="auth">
    <element name="validateUser">
      <element name="username">
        <data type="string">
          <param name="pattern">.+</param>
        </data>
      </element>
      <element name="password">
        <data type="string">
          <param name="pattern">.+</param>
        </data>
      </element>
    </element>
  </element>
</element>

答案 2 :(得分:0)

或者,使用minLength似乎比正则表达式更直接,更清晰。 (这也需要XSD数据类型。)

<element name="amhAPI" xmlns="http://relaxng.org/ns/structure/1.0"
  datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <element name="auth">
    <element name="validateUser">
      <element name="username">
        <data type="string">
          <param name="minLength">1</param>
        </data>
      </element>
      <element name="password">
        <data type="string">
          <param name="minLength">1</param>
        </data>
      </element>
    </element>
  </element>
</element>