XSD正则表达式不匹配

时间:2013-01-27 17:29:35

标签: regex xsd

我正在根据其他人的XSD规范创建一个XML文件,但我无法弄清楚它为什么不验证。

以下是规则:

<xs:simpleType name="NonEmptyStringType">
    <xs:restriction base="xs:string">
        <xs:minLength value="1" />
        <xs:pattern value="[^\t\n\r]*[^\s][^\t\n\r]*" />
    </xs:restriction>
</xs:simpleType>

我在其中阅读了如下模式:

  • [^\t\n\r]*匹配任何非制表符,换行符或空格返回0次或更多次
  • [^\s]匹配任何不是空格的内容
  • [^\t\n\r]*匹配任何非制表符,换行符或空格返回0次或更多次

以及以下许多不匹配的xml之一的示例:

        <Zipcode>3506 RT</Zipcode>

根据xmllint,它不匹配3506 RT(或3506RT以及我希望匹配的许多其他内容),并出现以下错误:

element Zipcode: Schemas validity error : Element '{http://www.reeleezee.nl/taxonomy/1.23}Zipcode': [facet 'pattern'] The value '3506 RT' is not accepted by the pattern '[^\t\n\r]*[^\s][^\t\n\r]*'.

对我不解释的内容有任何暗示吗? (我不明白他们的NonEmptyStringType btw的严格性,我只会使用。+)


根据要求,这是zipcode声明:

<xs:element name="Zipcode" minOccurs="0" nillable="true" rse:CanIgnore="true">
    <xs:annotation>
        <xs:documentation>Postcode</xs:documentation>
    </xs:annotation>
    <xs:simpleType>
        <xs:restriction base="NonEmptyStringType">
            <xs:maxLength value="10" />
        </xs:restriction>
    </xs:simpleType>
</xs:element>

如您所见,这链接回NonEmptyStringType中的模式(上面发布的第一条规则)

3 个答案:

答案 0 :(得分:2)

这个正则表达式看起来很好。我认为这是你的验证工具中的一个错误...它们在边缘情况下经常出错。

好的,刚刚检查过:xerces接受了它; xmllint失败(我看到你正在使用xmllint)。我在过去曾多次发现xerces是正确的,xmllint在异常情况下有问题。这个正则表达式很不寻常。 (我不得不说,我真的很喜欢xmllint,它真的很快,但是xsd规范是巨大的,复杂的和令人困惑的,并且xmllint人们还没有把所有边缘情况都钉在上面。)

我尝试过的两个在线验证器也接受了它:http://www.utilities-online.info/xsdvalidationhttp://www.freeformatter.com/xml-validator-xsd.html

BTW:对于xerces,我下载了他们的java版本,发现他们的班级jaxp.SourceValidator是验证的最佳工具。但我相信它已经是java中的相同代码了。


编辑我在xerces中做了一些测试,以确保正则表达式可以失败(即它是活动的)。如果任何地方都有\n,则会失败。 (同样适用于\t,但我没有测试\r)。

检查规范,\s定义为[#x20\t\n\r] (在this table中)。这清楚表明正则表达式说你不能在任何地方{/ 1}},\t\n 。但是你可以拥有任意数量的文字空格字符(\r),只要它们不是所有空格字符(即至少有一个非空格字符) -space char,匹配#x20 - btw可以将其标记为[^\s])。 Xerces证实了这一点:所有空格都会出错。

也许他们想要允许空间文字(填充和散布),前提是那里有一些值(即不是所有空格)。

答案 1 :(得分:1)

[^\s] match anything that is not a space

但输入字符串3506 RT有空格!

我认为这就是它失败的原因:) 因为[^\t\n\r]通过了3506,之后您不期望空格字符[^\s],但它出现了! [^\t\n\r]也会通过,因为下一组字符为RT

所以你应该声明的是:

<xs:pattern value="[^\t\n\r\s]*[\s][^\t\n\r\s]*" />

现在这将允许

  1. NOT \t, \n, \r and \s对你希望添加的模式更严格的任何内容+只有在开头有至少一个非空白字符时才允许使用字符串。
  2. 空格字符:我们可以通过声明这样[\s]?来将其作为可选字符。允许一次或根本不允许。所以空间角色不能重复。
  3. 再次NOT \t, \n, \r and \s
  4. <xs:pattern value="[^\t\n\r\s]+[\s]?[^\t\n\r\s]*" />

    实际上,通过验证数字和字母字符而不是[^\t\n\r\s]声明,可以使它更严格..

    希望它有所帮助!如果有任何问题困扰你,请告诉我。

答案 2 :(得分:0)

我不相信\ r \ n是一个空格,它是一个回车符(类似于\ n换行符)。您可能希望将其替换为\ s或仅替换实际的文字“”。