【问题标题】:XML UTF8 charset boundsXML UTF8 字符集范围
【发布时间】:2017-09-29 22:30:35
【问题描述】:

我正在开发一个 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 字符串,所有内容都将在#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+?

【问题讨论】:

  • XML 规范是按照 Unicode 代码点来处理数据的,而不是任何特定编码的字节,如 UTF-8、UTF-16 等。如果你有 UTF 数据,你必须转换在处理它们之前将其代码单元序列转换为 UTF-32 代码单元(也称为 Unicode 代码点)。

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


【解决方案1】:

#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/case 语句中:

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 代码单元。

【讨论】:

  • 谢谢,正是我想要的。
猜你喜欢
  • 1970-01-01
  • 2016-11-21
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 2016-05-31
  • 2016-10-29
  • 2015-07-23
  • 2012-04-27
相关资源
最近更新 更多