可以在XSD中实现Unicode规范无格式匹配吗?

问题描述:

我正在研究一种数据模型的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的标准规范无匹配匹配算法相同的结果,那么我可以忍受我得到的结果。

你问:

有没有产生在这方面真正的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)'。 –