Define an element as non-empty in RelaxNG

瘦欲@ 提交于 2019-12-05 05:23:11

问题


I've started using RelaxNG to specify XML message schemas, and using PHP DOMDocument to validate and parse incoming messages, but can't figure out how to define a text node so that it cannot be empty. Example schema:

<?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>

However, the message below is being validated as correct by the DOMDocument::relaxNGValidate method (since relaxng matches any arbitrary string [including an empty one] with the text pattern) and is equivalent to ):

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

Because of this, I have to add in a bunch of checks and validation for fields that are not supposed to be empty, which could be removed if the validator identified them as non-empty elements.

Is there a way to force non-empty text?


回答1:


If your RELAX NG validator supports XSD data types (most do), then you can use regular expressions to refine the constraints for text content:

<?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:


The preceding solutions don't always work very well. If you set the minLength facet to "1", one single whitespace character (or one newline character) is accepted. If you use the pattern .*[\S]+.* you can't insert any newline character, but this is a good thing only for "username" and "password" (see the example above).

Regular expressions are the right way, but to define an element as non-empty the better solution (for me) is the generic pattern: (.|\n|\r)*\S(.|\n|\r)*, so you can also use newline characters wherever you want.




回答3:


Alternatively, using minLength seems more direct and cleaner than regexes. (This also requires XSD data types.)

<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>


来源:https://stackoverflow.com/questions/6195885/define-an-element-as-non-empty-in-relaxng

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!