lxml解析含阿拉伯语的XML时输出字符实体 如何配置Unicode解析?
问题描述
我有一个格式化后的S005_179-205M-2 XML文件,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <TEI xmlns="http://www.tei-c.org/ns/1.0" xml:base="http://example.org" xml:id="example_v1" > <teiHeader> <fileDesc> <titleStmt> <title>test</title> </titleStmt> <publicationStmt> <p>test</p> </publicationStmt> <sourceDesc> <p>test</p> </sourceDesc> </fileDesc> </teiHeader> <text xml:lang="ar"> <body> <div type="chapter" n="5" xml:lang="ar"> <div type="section" n="5.179"> <head type="30">الْقَوْلُ فِي تَأْوِيلِ قَوْلِهِ : <quote type="quran" n="5:74">أَفَلا يَتُوبُونَ إِلَى اللَّهِ وَيَسْتَغْفِرُونَهُ وَاللَّهُ غَفُورٌ رَحِيمٌ </quote></head> <p n="nothadith" ana="adyan kalam yes">يقول تعالى ذكره : أفلا يرجع هذان الفريقان <name role="organization">الكافران</name> ، القائل أحدهما : <quote type="quran" n="5:72">إِنَّ اللَّهَ هُوَ <name role="person">الْمَسِيحُ ابْنُ مَرْيَمَ</name> </quote> ، والآخر القائل : <quote type="quran" n="5:73">إِنَّ اللَّهَ ثَالِثُ ثَلاثَةٍ </quote> ، عما قالا من ذلك ، و ينيبان مما قالا ونطقا به من كفرهما ، ويسألان ربهما المغفرة مما قالا : <quote type="quran" n="5:74" >وَاللَّهُ غَفُورٌ </quote> ، لذنوب التائبين من خلقه ، المنيبين إلى <pb type="turki" n="8:582"/> طاعته بعد معصيتهم ، <quote type="quran" n="5:34">رَحِيمٌ </quote> بهم في قبوله توبتَهم ، ومراجعتَهم إلى ما يحب مما يكره ، فيصفح بذلك من فعلهم عما سلف من إجرامهم قبل ذلك . </p> </div> </div> </body> </text> </TEI>
我使用如下代码读取该文件:
from lxml import etree tree = etree.parse('S005_179-205M-2 formated.xml')
随后执行以下代码打印XML树:
root = tree.getroot() print(etree.tostring(root))
输出结果中阿拉伯语文本全部显示为字符实体,未正常展示阿拉伯语。经排查确认是输出时编码设置问题,请问如何配置可正常输出Unicode格式的阿拉伯语文本?
解决方案
该问题并非解析阶段读取失败,lxml在解析时已经正确识别了XML的UTF-8编码、将阿拉伯语文本存储为Unicode格式,问题出在etree.tostring的默认输出配置:默认采用ASCII编码输出,非ASCII字符会被转义为字符实体。
按如下两种方式修改输出代码即可:
方式1:指定UTF-8编码输出
# 输出带缩进的UTF-8格式XML,解码为字符串后打印 print(etree.tostring(root, encoding='utf-8', pretty_print=True).decode('utf-8'))
参数说明:
encoding='utf-8':指定输出编码为UTF-8,不会转义非ASCII字符pretty_print=True:可选参数,保持XML的缩进格式,方便阅读- 末尾的
decode('utf-8'):将etree.tostring返回的bytes类型转为Python字符串,打印时可正常显示阿拉伯语
方式2:直接输出Unicode字符串
如果不需要bytes类型的输出结果,可以直接指定编码为unicode,省去解码步骤:
print(etree.tostring(root, encoding='unicode', pretty_print=True))
验证解析结果
你可以直接读取节点的text属性确认解析正确,无需修改解析配置:
# 因为XML带命名空间,查询时需要指定命名空间 ns = {'tei': 'http://www.tei-c.org/ns/1.0'} head_node = root.find('.//tei:head', namespaces=ns) print(head_node.text)
运行后会直接输出正常的阿拉伯语文本,说明解析阶段无问题。
内容的提问来源于stack exchange,提问作者zaid saeed
相关产品推荐
相关产品推荐

