我正在根据其他人的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]*
匹配任何非制表符,换行符或[^\s]
匹配任何不是空格的内容[^\t\n\r]*
匹配任何非制表符,换行符或以及以下许多不匹配的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中的模式(上面发布的第一条规则)
答案 0 :(得分:2)
这个正则表达式看起来很好。我认为这是你的验证工具中的一个错误...它们在边缘情况下经常出错。
好的,刚刚检查过:xerces接受了它; xmllint失败(我看到你正在使用xmllint)。我在过去曾多次发现xerces是正确的,xmllint在异常情况下有问题。这个正则表达式很不寻常。 (我不得不说,我真的很喜欢xmllint,它真的很快,但是xsd规范是巨大的,复杂的和令人困惑的,并且xmllint人们还没有把所有边缘情况都钉在上面。)
我尝试过的两个在线验证器也接受了它:http://www.utilities-online.info/xsdvalidation和http://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]*" />
现在这将允许
NOT \t, \n, \r and \s
对你希望添加的模式更严格的任何内容+只有在开头有至少一个非空白字符时才允许使用字符串。[\s]?
来将其作为可选字符。允许一次或根本不允许。所以空间角色不能重复。NOT \t, \n, \r and \s
。 <xs:pattern value="[^\t\n\r\s]+[\s]?[^\t\n\r\s]*" />
实际上,通过验证数字和字母字符而不是[^\t\n\r\s]
声明,可以使它更严格..
希望它有所帮助!如果有任何问题困扰你,请告诉我。
答案 2 :(得分:0)
我不相信\ r \ n是一个空格,它是一个回车符(类似于\ n换行符)。您可能希望将其替换为\ s或仅替换实际的文字“”。