簡體   English   中英

Python ElementTree 生成格式不正確的帶有特殊字符“\\x0b”的 XML 文件

[英]Python ElementTree generate not well formed XML file with special character '\x0b'

我使用ElementTree生成帶有'\\x0b'特殊字符的xml,然后使用minidom來解析它。 它會拋出not well-formed錯誤。

import xml.etree.ElementTree as ET
from xml.dom import minidom
root = ET.Element('root')
root.text='\x0b'
xml = ET.tostring(root, 'UTF-8')
print(xml)
pretty_tree = minidom.parseString(xml)

生成的 XML : <root>\\x0b</root>

錯誤

Traceback (most recent call last):
  File "testXml.py", line 7, in <module>
    pretty_tree = minidom.parseString(xml)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/xml/dom/minidom.py", line 1968, in parseString
    return expatbuilder.parseString(string)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/xml/dom/expatbuilder.py", line 925, in parseString
    return builder.parseString(string)
  File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/xml/dom/expatbuilder.py", line 223, in parseString
    parser.Parse(string, True)
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 6

此行為過去曾作為錯誤提出,並已解決為“無法修復”。

ElementTree 模塊作者評論

對於 ET,[這種行為] 非常有意。 驗證每個應用程序提供的數據會降低所有應用程序的性能,即使只有一小部分人會嘗試序列化無法用 XML 表示的數據。

結束評論(由lxml的維護者,他也是 Python 核心開發者)包括以下觀察:

這是一個棘手的決定。 例如,lxml 驗證用戶輸入,但那是因為無論如何它都必須處理它,並且直接在輸入上進行處理(並且在 C 代碼中非常有效)。 另一方面,ET 對於它允許用戶做什么並且不對用戶輸入應用太多處理是相當寬松的。 它甚至在處理過程中允許無效樹,並且僅在請求序列化它時才期望樹是可序列化的。

我認為這是一種公平的行為,因為大多數用戶輸入都可以,並且不需要因為驗證所有輸入而遭受性能損失。 例如,空字符在文本中是非常罕見的,我認為讓用戶自己處理少數可能發生的情況是合理的。

...

最后,真正關心正確輸出的用戶應該序列化對其進行某種模式驗證,因為這不僅會檢測數據問題,還會檢測結構和邏輯問題(例如缺失或空屬性),特別是針對他們的目標數據格式。 在某些情況下,它甚至可能檢測到由於服務器機器中舊的非 ECC RAM 造成的隨機數據損壞。 :)

...

所以總而言之, ET.tostring會生成ET.tostring不正確的 xml,這是設計ET.tostring 如有必要,可以使用ET.fromstring或其他解析器解析輸出以檢查其格式是否ET.fromstring 或者,可以使用 lxml 代替 ElementTree。

\\x0b是 XML 限制字符。 這個問題的答案中有對有效和受限字符的很好的描述。

作為我自己的一種解決方法,我編寫了一個輔助方法來在保存到 XML 模型之前清除受限制的字符:

def clean(str):
  return re.sub(r'[^\u0009\u000A\u000D\u0020-\uD7FF\uE000-\uFFFD\u10000-\u10FFF]+', '', str)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM