2012-03-27 62 views
0

我希望我的XSD验证字符串的内容。具体而言,我想验证某个字符串不会发生XSD限制否定匹配的字符串

考虑这个规则,它将验证我的字符串是否发生。寻找所有Link元件开始与该特定字符串:/site/example.com

<xs:element name="Link" type="xs:normalizedString" minOccurs="0"> 
    <xs:simpleType> 
    <xs:restriction base="xs:token"> 
     <xs:pattern value="(/site/example\.com).*"/> 
    </xs:restriction> 
    </xs:simpleType> 
</xs:element>     

换句话说,上面的表达式验证所有Link元件与/site/example.com启动。如何反转上述表达式,以便它**验证没有Link元素以/site/example.com开头?

我试过,没有运气以下正则表达式:/[^(site/example\.com)].*,所以这是行不通的:

不工作的战略1(单个字符的否定) 我我知道这可能适用于否定单个字符,因为这个问题确实如此:XML schema restriction pattern for not allowing empty strings

在这个问题<xs:pattern value=".*[^\s].*" />

但否定只有一个字符不会在这种情况下工作,因为它会失败,正确的建议图案:

/site/example.com

但它也会错误地失败

/solutions

不工作的战略2(高级正则表达式前瞻) 根据这太问题(Regular expression to match a line that doesn't contain a word?),你可以用负先行(?!expr)解决这个问题。

因此,这将在普通的正则表达式的工作:

^* $

现在,不幸的是XSD验证只支持有限的正则表达式((/网站/ example.com)?!)。根据这个网站,不支持lookahead:regular-expressions.info -- xsd

这几乎描述了我到现在为止所尝试的。

我的问题是,我如何否定XSD架构中的正则表达式?

回答

1

你没有提到你是否绑定了XML Schema 1.0和XPath 1.0,但是如果没有的话,可以用xs:assert's来实现你的目标,这可能需要一些工作 - 这是从记忆里...):

<xs:element name="Link" type="xs:normalizedString" minOccurs="0"> 
    <xs:simpleType> 
    <xs:restriction base="xs:token"> 
     <xs:assert test="not(fn:starts-with($value , '/site/example.com'))" /> 
    </xs:restriction> 
    </xs:simpleType> 
</xs:element> 

可能感兴趣的一些链接:

http://www.ibm.com/developerworks/library/x-xml11pt2/

http://www.w3.org/TR/xpath-functions/#func-starts-with

干杯,

+0

非常感谢,我将不得不看看这个 – 2012-03-27 20:32:52

2

这是简单的XSD 1.1,在那里你可以用断言做确保该值不以您指定的字符串开头。但从概念上讲,即使在XSD 1.0和简单的正则表达式中它也很简单:要确保字符串不以“/site/example.com”开头。如果它没有开始这样一来,你就会有一个一系列关于字符串事实的逻辑连词:

  • 子(。,1,1)= '/'
  • 子(,2, 1)= 's' 的
  • 子(。,3,1)= '我'
  • ...
  • 子(17,1)= 'M'

你想否定事实的这一连词。现在,根据德摩根定律,〜(a和b以及...和z)相当于(〜a或〜b或...或〜z)。所以,你可以做你的需要通过编写以下方面的脱节:

[^/].* 
    |.([^s].*)? 
    |.{2}([^i].*)? 
    |.{3}([^t].*)? 
    |.{4}([^e].*)? 
    |.{5}([^/].*)? 
    |.{6}([^e].*)? 
    |.{7}([^x].*)? 
    |.{8}([^a].*)? 
    |.{9}([^m].*)? 
    |.{10}([^p].*)? 
    |.{11}([^l].*)? 
    |.{12}([^e].*)? 
    |.{13}([^\.].*)? 
    |.{14}([^c].*)? 
    |.{15}([^o].*)? 
    |.{16}([^m].*)? 

在形式[^s].*已经被包裹在(...)?的子表达式以上每个术语 - 术语.{2}([^i].*)?意味着两个字符开头的任何字符串如果第三个字符不是i或者根本没有第三个字符,那么就可以。这可以确保长度不超过17个字符的字符串不会被排除,即使它们恰好是禁止字符串的前缀。

当然,要在XSD模式文档中使用它,您需要删除所有的空格,这使得正则表达式更难读取。

[此外,2016年6月]另见this related and more general question