2017-09-12 64 views
1

我正在研究一種數據模型的XML模式,該數據模型涉及基本上來自所有Unicode字符的不區分大小寫的鍵。在這種情況下,根據Unicode規範無匹配匹配算法(Chapter 3 of version 10.0 of the Unicode specification中的定義D145)定義「不區分大小寫」。無匹配匹配與XSD 1.1身份約束不匹配,所以我正在考慮用於定義必要的密鑰唯一性約束的各種備選方案,理想情況下不會丟失密鑰的原始未規範化形式。可以在XSD中實現Unicode規範無格式匹配嗎?

目前,我正在尋找簡單的約束鍵來呈現與規範無匹配匹配一致的案例摺疊歸一化形式,以便它們可以直接相互比較。爲了有用,它不能依賴擴展或特定於實現的行爲,儘管我願意依賴定義明確的可選行爲,例如使用unicode-normalize() XPath函數進行規範化以形成NFD。在未來,我可能還想驗證兩個字符串是規範的無匹配匹配(即將兩個屬性值或元素的文本內容及其屬性值之一約束爲彼此的規範無匹配匹配) ,但這是一個單獨的問題。

這裏有一個簡單的例子架構,我認爲出來的結果很接近做我想要什麼:

<xsd:schema 
    version="1.1" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:fn="http://www.w3.org/2005/xpath-functions" 
    xmlns:my="urn:x-myns" 
    targetNamespace="urn:x-myns" 
    elementFormDefault="qualified"> 

    <xsd:element name="table" type="my:tableType"> 
    <xsd:key name="keyKey"> 
     <xsd:selector xpath="my:entry"/> 
     <xsd:field xpath="@key"/> 
    </xsd:key> 
    </xsd:element> 

    <xsd:complexType name="tableType"> 
    <xsd:sequence> 
     <xsd:element name="entry" type="my:entryType" 
        minOccurs="0" maxOccurs="unbounded"/> 
    </xsd:sequence> 
    </xsd:complexType> 

    <xsd:complexType name="entryType"> 
    <xsd:simpleContent> 
     <xsd:extension base="xsd:string"> 
     <xsd:attribute name="key" type="xsd:string"/> 

     <!-- MY BEST ATTEMPT SO FAR: --> 
     <xsd:assert test="@key=fn:unicode-normalize(fn:lower-case(
      fn:unicode-normalize(@key, 'NFD')), 'NFD')" /> 

     </xsd:extension> 
    </xsd:simpleContent> 
    </xsd:complexType> 

</xsd:schema> 

這足以拒絕

<table xmlns="urn:x-myns"> 
    <entry key="Clé">Value1</entry> 
</table> 

(「CLE」應作爲「CLE & #x0301;「或相同字符序列的等效表示),但它不完全匹配數據的本機規範化,因爲在某些情況下,Unicode大小寫摺疊不等同於較低的大小寫。所以,

  • 有沒有產生在這方面真正的Unicode的情況下折規範化的形式,受到我提出的限制的方法嗎?
  • 我真的需要嗎?如果由我的模式中的斷言測試的表單作爲無狀態匹配行爲的基礎,它總是產生與Unicode的標準規範無匹配匹配算法相同的結果,那麼我可以忍受我得到的結果。

回答

1

你問:

有沒有產生在這方面真正的Unicode的情況下折規範化的形式,受到我提出的限制的方法嗎?

如果「真正的Unicode大小寫摺疊規範化的形式」你的意思是應用的Unicode Case_Folding()映射到字符串的結果,我想答案是(可能)「不」,這是爲什麼。

對於您正在使用的方法,您需要一個可以在斷言中調用的函數(或者在您的示例中是函數的組合)。因此,當且僅當有一個可以調用以產生它的內置函數的簡單組合時,纔有可能獲得真正的大小寫摺疊形式。

如果Case_Folding只是將新字符替換爲舊字符,理論上可以通過調用translate()來處理,但參數字符串將無法管理。但是Case_Folding映射(如果我已經理解了指向正確的文檔)某些字符轉換爲字符串(和/或某些字符串轉換爲字符串),這使得translate()不可用。

沒有通過的情況下,摺疊和進入下套管條目在Unicode字符數據庫會進入,我不知道它是可以證明某些它無法做到的。 (也許呼籲小寫(),然後明智地使用replace()會做的伎倆 - 但我認爲它太笨拙。

當然可以編寫一個XQuery或XSLT函數來做如果你能找到一個願意接受XPath 3.0的XSD模式驗證器,而不是在XSD斷言中聲明一個函數然而,編寫你自己的函數在理論上是可能的,但是除非你可以將盡可能多的細節卸載到Unicode數據庫的XML表示,這意味着它只有在XSD處理器是願意評估對doc()的調用。

因此,在實踐中,我認爲答案是否定的,除非你願意去不尋常的長度讓它發生也有一些運氣。

我真的需要嗎?如果由我的模式中的斷言測試的表單作爲無狀態匹配行爲的基礎,它總是產生與Unicode的標準規範無匹配匹配算法相同的結果,那麼我可以忍受我得到的結果。

我想在這裏也一樣,答案是 「否」。您指向的URI節「默認大小寫摺疊」的第四段寫道:

這被認爲是下任滿 大小寫轉換對方的情況下,變體的任何兩個字符串,toUppercase(X ),toLowercase(X),或toTitlecase(X)將摺疊由toCasefold(X相同 串)操作

由於XPath的小寫()函數被指定爲執行的Unicode小寫映射,我認爲這給你的結果是,在Unicode toCasefold()操作下,小寫($ S1)eq小寫($ S2)的任何字符串S1和S2將相等。以Unicode段落的措辭留下了一些字符串這都不是彼此的意志倍,toCasefold()在相同字符串的情況下變種,但我希望所有他們的意思是這種情況下,摺疊影響正常化以及可能性作爲外殼。如果是這樣,那麼我認爲你對unicode-normalize()的調用將處理這些情況。 (如果還有其他toCasefold()返回相同值的字符串對,但unicode-normalize(lower-case())不會,那麼你的斷言將無法接受一些你希望接受的對。對字符串的是什麼?)

這個答案不太脆,比我希望我能做到,我懷疑我跟你說什麼你不知道的。如果沒有在Unicode數據庫比我有時間研究更多的時間,我不認爲一個更確切的答案很可能是可能的。但是,如果你主要希望獨立觀察員確認你看起來在正確的軌道上,我當然可以做到這一點。幹得好!還有祝你好運!

+0

我不買你的說法,'FN之間的區別:小寫()'和Unicode'toCaseFold()'不會有所作爲。Unicode似乎在說'toCaseFold(s)== toCaseFold(小寫字母)'表示所有的Unicode字符串's',但它並不遵循'toCaseFold(s)==小寫( s)'或unicode-normalize(toCaseFold(s),'NFD')== unicode-normalize(小寫字母,'NFD')'。 (我很抱歉混合XPath和Unicode規範函數的僞表達式。) –

+0

儘管如此,我很欣賞證實我不能擁有我想要的東西(ob-Jagger在這裏)。我認爲我有一個合理的近似值,從文獻的角度來看,我認爲這是令人滿意的。無論如何,我希望如此,因爲我沒有辦法做得更好。 –

+0

關於toCaseFold()和lower-case()的關係,你已經說服了我,Unicode規範意味着你說什麼。但是,我認爲你的問題的關鍵條件不是你引用的那個,而是對於所有的s和t'unicode-normalize(小寫字母,'NFD')== unicode-normalize(小寫(t),'NFD')iff toCaseFold(s)== toCaseFold(t)'。 –

相關問題