XML UTF8字符集边界

时间:2017-05-02 11:54:50

标签: xml swift unicode utf-8 character-encoding

我正在使用XML库来更全面地了解它的全部内容。我遇到了需要转义并验证XML的字符串。查看人们通常只提及&和引号<,>

挖掘我找到了实际的规格:https://www.w3.org/TR/REC-xml/#charsets 其中说明:

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

很棒,完美地布置在有效角色上。我的问题是UTF-8是8位块(代码单位?),最大值为256的十进制值。如果我严格使用UTF-8字符串,一切都将在{{1}之下范围和最终范围内没有任何内容。

在我看来,使用#xD7FF对上部范围进行边界检查是没有意义的,我知道字符集/ unicode可能充满了陷阱,是否有我遗漏的东西?

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

UTF-8

我假设这些上限是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? } +?

1 个答案:

答案 0 :(得分:0)

XML规范中的

#xA#xE000#x10000等是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 { }

您将获得该范围内的一系列UTF-8代码单元(UInt8) 0 ... 255,每个Unicode标量值由1,2,3表示 或4个UTF-8代码单元。