2017-05-02 204 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