python解析xml模块html模块,python – 使用(X)HTML实体解析XML

这里的问题是XML中唯一有效的助记符是“amp”,“lt”和“”.这意味着几乎所有(X)HTML命名实体必须使用

XML 1.1 spec中定义的

entity declaration markup在DTD中定义.如果文档是独立的,则应使用内联DTD完成此操作:

]>

1 >

2008©

141100

xml.etree.ElementTree中的XMLParser使用xml.parsers.expat来进行实际的解析.在XMLParser的init参数中,’predefined HTML entities‘有一个空格,但该参数尚未实现.在init方法中创建一个空的dict命名实体,这是用于查找未定义实体的内容.

我不认为expat(通过扩展,ET XMLParser)能够处理切换命名空间到类似于XHMTL以解决这个问题.可能是因为它不会获取外部命名空间定义(我尝试使xmlns =“http://www.w3.org/1999/xhtml”为数据元素的默认命名空间,但它没有很好地播放),但我无法确认那.默认情况下,expat会引发对非XML实体的错误,但您可以通过定义外部DOCTYPE来解决这个错误 – 这导致expat解析器将未定义的实体条目传回回ET.XMLParser的_default()方法.

_default()方法查找XMLParser实例中的实体dict,如果找到匹配的键,它将使用关联的值替换实体.这将维护问题中提到的Python-2.x语法.

解决方案:

>如果数据没有外部DOCTYPE,并且具有(X)HTML助记符实体,那么你是不幸的.它是无效的XML和外部是正确的抛出一个错误.您应该添加外部DOCTYPE.

>如果数据具有外部DOCTYPE,则可以使用旧的语法将助记符名称映射到字符.注意:您应该在py3k中使用chr() – unichr()不再是有效的名称

>或者,您可以使用html.entities.html5更新XMLParser.entity,将所有有效的HTML5助记符实体映射到其字符.

>如果数据是XHTML,您可以将HTMLParser子类化为处理助记符实体,但这不会根据需要返回ElementTree.

这是我使用的代码片段 – 它通过HTMLParser解析XML与外部DOCTYPE(演示如何通过子类化来添加实体处理),ET.XMLParser与实体映射和expat(由于外部DOCTYPE,它将静默地忽略未定义的实体) .有一个有效的XML实体(& gt)和一个未定义的实体(& copy;),它与ET.XMLParser映射到chr(0x24B4).

from html.parser import HTMLParser

from html.entities import name2codepoint

import xml.etree.ElementTree as ET

import xml.parsers.expat as expat

xml = '''<?xml version="1.0"?>

1>

2008©

141100

'''

# HTMLParser subclass which handles entities

print('=== HTMLParser')

class MyHTMLParser(HTMLParser):

def handle_starttag(self, name, attrs):

print('Start element:', name, attrs)

def handle_endtag(self, name):

print('End element:', name)

def handle_data(self, data):

print('Character data:', repr(data))

def handle_entityref(self, name):

self.handle_data(chr(name2codepoint[name]))

htmlparser = MyHTMLParser()

htmlparser.feed(xml)

# ET.XMLParser parse

print('=== XMLParser')

parser = ET.XMLParser()

parser.entity['copy'] = chr(0x24B8)

root = ET.fromstring(xml, parser)

print(ET.tostring(root))

for elem in root:

print(elem.tag, ' - ', elem.attrib)

for subelem in elem:

print(subelem.tag, ' - ', subelem.attrib, ' - ', subelem.text)

# Expat parse

def start_element(name, attrs):

print('Start element:', name, attrs)

def end_element(name):

print('End element:', name)

def char_data(data):

print('Character data:', repr(data))

print('=== Expat')

expatparser = expat.ParserCreate()

expatparser.StartElementHandler = start_element

expatparser.EndElementHandler = end_element

expatparser.CharacterDataHandler = char_data

expatparser.Parse(xml)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值