2017-05-02 162 views
0

我正在研究XML库以更全面地了解它的全部内容。我遇到了需要转义和验证XML的字符串。环顾人们一般只提&和报价和<,>XML UTF8字符集边界

我周围挖发现实际规格:https://www.w3.org/TR/REC-xml/#charsets 其中规定:

Char ::=  #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] 

大,对有效字符完美布局。我的问题是UTF-8是8位块(代码单位?),它将以十进制值256为最大值。如果我严格使用UTF-8字符串,则所有内容都将在#xD7FF范围内,最终范围内不会有任何内容。

在我看来,使用UTF-8做上边界检查是无意义的,我知道字符集/ unicode可以充满陷阱,有什么我失踪?

例如,我正在使用Swift。所以如果我去

let someString = "abcdefg" 
for char in someString.utf8 { 
// char is a UTF8.CodeUnit which is a type alias to UInt8, 
// comparing a UInt8 to a value of something over 256 is just silly? 
} 

我假设这些上限范围为UTF-16 +?

+0

XML规范是用于处理Unicode代码点的数据,而不是任何特定编码的字节,如UTF-8,UTF-16等。如果您有UTF数据,则必须将其代码单元序列转换为在处理它们之前,UTF-32代码单元(aka Unicode代码点)。 –

回答

0

#xA#xE000#x10000等在XML规范是Unicode Scalar Values(又名Unicode代码点,但不包括高代理和低代理码点为UTF-16保留的)。这就是你列举unicodeScalars视图中的字符串时:

for unicode in someString.unicodeScalars { 
    let value = unicode.value // an `UInt32` 

    // .... 
} 

然后你就可以平等测试Unicode标值:

if value == 0x10000 { 

} 

或用于一系列遏制:

if 0xE000...0xFFFD ~= value { 

} 

或在开关/壳体声明中:

switch value { 
case 0x0A, 0x0D: 
    // ... 
case 0xE000...0xFFFD: 
    // ... 
default: 
    // ... 
} 

当枚举utf8视图:

for char in someString.utf8 { } 

您将在范围 0 ... 255获得的UTF-8编码单元的序列(UInt8),并且每个Unicode标值由1表示, 2,3 或4个UTF-8编码单元。

+0

谢谢,正是我在找的东西。 – utahwithak