python standard_library XML minidom

python 标准库 minidom

每日一词:

Order 美音 [‘ɔrdər] 英音 [‘ɔː(r)də(r) ]

词根解释:

order,ord,ordin(ordain) = ord,ordin
来自拉丁语的ord,ordin 意为to order,变形为ordain。

n.顺序;命令;勋章;规则

v.命令;整理;定货;下令

网络订单;秩序;目

下面是一个本地翻译的例句:

The writexml() method now preserves the attribute order specified by the user.

此处的order结合上下文,我翻译成 规则

writexml() 方法允许用户保留属性规则声明.

源代码: Lib / xml / dom / minidom.py

xml.dom.minidom是文档对象模型接口的最小实现,其API类似于其他语言。它的目标是比完整的DOM更简单,也更小。不熟悉DOM的用户应考虑使用该xml.etree.ElementTree模块进行XML处理。

警告:该xml.dom.minidom模块对恶意构建的数据不安全。如果您需要解析不可信或未经身份验证的数据,请参阅 XML 漏洞

通常,DOM应用程序首先将一些XML解析为DOM。有了xml.dom.minidom,这是通过解析函数完成的:

1
2
3
4
5
6
7
8
from xml.dom.minidom import parse, parseString

dom1 = parse('c:\\temp\\mydata.xml') # parse an XML file by name

datasource = open('c:\\temp\\mydata.xml')
dom2 = parse(datasource) # parse an open file

dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')

parse()函数可以采用文件名或打开的文件对象。

1
xml.dom.minidom.parse(filename_or_file[, parser[, bufsize]])

Document从给定的输入中被返回 。filename_or_file可以是文件名,也可以是文件类对象。解析器(如果有的话)必须是SAX2解析器对象。该函数将更改解析器的文档处理程序并激活命名空间支持; 其他解析器配置(如设置实体解析器)必须事先完成。

如果你在一个字符串中有XML,你可以使用这个parseString()函数:

1
xml.dom.minidom.parseString(string[, parser])

返回一个表示字符串的文档。 此方法为该字符串创建一个StringIO对象,并将其传递给parse()。

这两个函数都会返回一个Document代表文档内容的对象。

parse()parseString()功能做的是一个“DOM生成器”,可以从任何SAX解析器解析接受事件并将它们转换成DOM树连接XML解析器。这些功能的名称可能是误导性的,但在学习接口时很容易理解。文档的解析将在这些函数返回之前完成; 只是这些函数本身不提供解析器实现。

您也可以通过调用“DOM实现”对象上的方法来创建文档。 您可以通过调用xml.dom包中的getDOMImplementation()函数或xml.dom.minidom模块来获取此对象。 使用xml.dom.minidom模块中的实现将始终从minidom实现中返回一个Document实例,而来自xml.dom的版本可能会提供一个替代实现(如果您安装了PyXML包,则可能会发生这种情况)。 一旦你有一个文档,你可以添加子节点来填充DOM:

1
2
3
4
5
6
7
8
from xml.dom.minidom import getDOMImplementation

impl = getDOMImplementation()

newdoc = impl.createDocument(None, "some_tag", None)
top_element = newdoc.documentElement
text = newdoc.createTextNode('Some textual content.')
top_element.appendChild(text)

一旦有了DOM文档对象,就可以通过其属性和方法访问XML文档的各个部分。这些属性在DOM规范中定义。文档对象的主要属性是documentElement属性。它为您提供了XML文档中的主要元素:包含所有其他元素的元素。这是一个示例程序:

1
2
dom3 = parseString("<myxml>Some data</myxml>")
assert dom3.documentElement.tagName == "myxml"

当你完成一个DOM树时,你可以选择调用unlink()方法来鼓励早期清理不需要的对象。 unlink()是DOM API的一个xml.dom.minidom专用扩展,它呈现节点及其后代实质上是无用的。 否则,Python的垃圾收集器将最终处理树中的对象。

扩展内容

文档对象模型(DOM)1级规范 W3C推荐的DOM支持xml.dom.minidom

DOM对象

Python的DOM API的定义是作为xml.dom模块文档的一部分给出的。本节列出了API和xml.dom.minidom

1
Node.unlink()

打破DOM内的内部引用,以便在没有循环GC的情况下在Python版本上进行垃圾回收。 即使循环GC可用,使用它也可以更快地提供大量内存,因此,在不再需要DOM对象时立即调用它是很好的做法。 这只需要在Document对象上调用,但可以在子节点上调用以放弃该节点的子节点。

1
Node.writexml(writer, indent="", addindent="", newl="")

将XML写入作者对象。 作者应该有一个与文件对象接口匹配的write()方法。 缩进参数是当前节点的缩进。 addindent参数是用于当前子节点的递增缩进。 newl参数指定用于终止换行符的字符串。

对于Document节点,可以使用其他关键字参数编码来指定XML标头的编码字段。

3.8版本中 writexml() 方法允许用户保留属性规则声明

1
Node.toxml([encoding])

将DOM表示的XML返回为字符串。

如果默认编码不能表示文档中的所有字符,那么没有参数时,XML标头不会指定编码,并且结果为Unicode字符串。使用UTF-8以外的编码对此字符串进行编码可能不正确,因为UTF-8是XML的默认编码。

使用显式编码 [1]参数,结果是指定编码中的字节字符串。建议始终指定此参数。为避免UnicodeError出现无法表示的文本数据时出现异常,应将编码参数指定为“utf-8”。

3.8版本中 toxml() 方法允许用户保留属性规则声明

1
Node.toprettyxml([indent=""[, newl=""[, encoding=""]]])

返回文档的完美版本。indent 指定缩进字符串,并默认为制表符; newl指定在每行末尾发射的字符串,默认为\n

3.8版本中 toprettyxml() 方法允许用户保留属性规则声明

以下标准DOM方法对xml.dom.minidom有特殊考虑:

1
Node.cloneNode(deep)

尽管此方法出现在与Python 2.0一起打包的xml.dom.minidom版本中,但它被严重破坏。 这已为后续版本纠正。

DOM例子

这个示例程序是一个简单程序的相当现实的例子。在这种特殊情况下,我们没有充分利用DOM的灵活性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import xml.dom.minidom

document = """\
<slideshow>
<title>Demo slideshow</title>
<slide><title>Slide title</title>
<point>This is a demo</point>
<point>Of a program for processing slides</point>
</slide>

<slide><title>Another demo slide</title>
<point>It is important</point>
<point>To have more than</point>
<point>one slide</point>
</slide>
</slideshow>
"""

dom = xml.dom.minidom.parseString(document)

def getText(nodelist):
rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc.append(node.data)
return ''.join(rc)

def handleSlideshow(slideshow):
print "<html>"
handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
slides = slideshow.getElementsByTagName("slide")
handleToc(slides)
handleSlides(slides)
print "</html>"

def handleSlides(slides):
for slide in slides:
handleSlide(slide)

def handleSlide(slide):
handleSlideTitle(slide.getElementsByTagName("title")[0])
handlePoints(slide.getElementsByTagName("point"))

def handleSlideshowTitle(title):
print "<title>%s</title>" % getText(title.childNodes)

def handleSlideTitle(title):
print "<h2>%s</h2>" % getText(title.childNodes)

def handlePoints(points):
print "<ul>"
for point in points:
handlePoint(point)
print "</ul>"

def handlePoint(point):
print "<li>%s</li>" % getText(point.childNodes)

def handleToc(slides):
for slide in slides:
title = slide.getElementsByTagName("title")[0]
print "<p>%s</p>" % getText(title.childNodes)

handleSlideshow(dom)

minidom和DOM标准

xml.dom.minidom模块本质上是一个DOM 1.0兼容的DOM,具有一些DOM 2功能(主要是名称空间功能)。

在Python中使用DOM接口非常简单。以下映射规则适用:

  • 接口通过实例对象访问。应用程序不应该自己实例化类; 他们应该使用Document对象上可用的创建者函数。派生接口支持来自基本接口的所有操作(和属性)以及任何新的操作。

  • 操作被用作方法。由于DOM只使用in参数,参数按正常顺序传递(从左到右)。没有可选参数。void操作返回None

  • IDL属性映射到实例属性。为了与Python的OMG IDL语言映射兼容,foo还可以通过访问器方法_get_foo()和访问属性_set_foo()readonly属性不能改变; 这不是在运行时强制执行的。

  • 类型short intunsigned intunsigned long long,和boolean所有映射到Python的整数对象。

  • DOMString类型映射到Python字符串。 xml.dom.minidom支持字节或Unicode字符串,但通常会生成Unicode字符串。 DOMString类型的值也可以是None,其中允许通过W3C的DOM规范获得IDL空值。

  • 常量声明映射到各自范围内的变量(例如xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE); 他们不能改变。

  • DOMException目前在xml.dom.minidom中不受支持。 相反,xml.dom.minidom使用标准Python异常,例如TypeError和AttributeError。

  • NodeList对象是使用Python的内置列表类型实现的。从Python 2.2开始,这些对象提供了DOM规范中定义的接口,但是对于早期版本的Python,它们不支持官方API。然而,它们比W3C建议中定义的接口更“Pythonic”。

以下接口在xml.dom.minidom中没有实现:

  • DOMTimeStamp

  • EntityReference

其中大多数反映了XML文档中的信息,这对大多数DOM用户来说并不普遍。

脚注、

XML输出中包含的编码字符串应符合相应的标准。例如,“UTF-8”是有效的,但“UTF8”不是。请参阅https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl和https://www.iana.org/assignments/character-sets/character-sets.xhtml。

坚持原创技术分享,您的支持将鼓励我继续创作!