2012-03-27 57 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