xml.dom.minidom
xml.dom.minidom
是文档对象模型接口的最小实现,其API与其他语言类似。它的目的是要比完整的DOM简单,而且要小得多。不熟悉DOM的用户应该考虑使用 xml.etree.ElementTree
用于XML处理的模块。
警告
这个 xml.dom.minidom
模块对恶意构造的数据不安全。如果需要分析不可信或未经身份验证的数据,请参阅 XML漏洞 .
DOM应用程序通常首先将一些XML解析为一个DOM。用 xml.dom.minidom
,这是通过解析函数完成的::
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()
函数可以采用文件名或打开的文件对象。
- xml.dom.minidom.parse(filename_or_file, parser=None, bufsize=None)
返回A
Document
从给定的输入。 filename_or_file 可以是文件名,也可以是类似文件的对象。 语法分析器 如果给定,则必须是SAX2解析器对象。此函数将更改解析器的文档处理程序并激活命名空间支持;其他解析器配置(如设置实体解析器)必须提前完成。
如果字符串中有XML,则可以使用 parseString()
改为函数:
- xml.dom.minidom.parseString(string, parser=None)
返回A
Document
代表了 string . 此方法创建一个io.StringIO
对象,并将其传递给parse()
.
两个函数都返回 Document
表示文档内容的对象。
什么? parse()
和 parseString()
函数的作用是将XML解析器与“dom builder”连接起来,后者可以接受来自任何SAX解析器的解析事件,并将其转换为dom树。函数的名称可能有误导性,但在学习接口时很容易掌握。文档的解析将在这些函数返回之前完成;只是这些函数本身不提供解析器实现。
您还可以创建 Document
通过对“dom实现”对象调用方法。您可以通过调用 getDOMImplementation()
功能在 xml.dom
封装还是 xml.dom.minidom
模块。一旦你拥有了 Document
,可以向其中添加子节点以填充dom::
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文档中的主要元素:保存所有其他元素的元素。下面是一个示例程序:
dom3 = parseString("<myxml>Some data</myxml>")
assert dom3.documentElement.tagName == "myxml"
完成DOM树后,可以选择调用 unlink()
方法来鼓励对现在不需要的对象进行早期清理。 unlink()
是一个 xml.dom.minidom
-呈现节点及其子代的DOM API的特定扩展在本质上是无用的。否则,Python的垃圾收集器最终将处理树中的对象。
参见
- Document Object Model (DOM) Level 1 Specification
W3C对支持的DOM的建议
xml.dom.minidom
.
DOM对象
python的dom api定义作为 xml.dom
模块文档。本节列出了API和 xml.dom.minidom
.
- Node.unlink()
中断dom中的内部引用,以便在不使用循环gc的Python版本上对其进行垃圾收集。即使循环GC可用,使用它也可以使大量内存更快地可用,因此在不再需要DOM对象时立即调用它是一种很好的实践。这只需要在
Document
对象,但可以在子节点上调用以丢弃该节点的子节点。通过使用
with
语句。以下代码将自动取消链接 dom 当with
块已退出::with xml.dom.minidom.parse(datasource) as dom: ... # Work with dom.
- Node.writexml(writer, indent='', addindent='', newl='', encoding=None, standalone=None)
将XML写入编写器对象。编写器接收文本而不是字节作为输入,它应该有一个
write()
与文件对象接口匹配的方法。这个 缩进 参数是当前节点的缩进。这个 附录 参数是用于当前子节点的增量缩进。这个 newl 参数指定用于终止换行符的字符串。对于
Document
节点,附加关键字参数 encoding 可用于指定XML头的编码字段。愚蠢地,明确地指出 独立的 参数导致将独立文档声明添加到XML文档的序言中。如果该值设置为 True , standalone="yes" 添加,否则设置为 "no" . 不声明参数将忽略文档中的声明。
在 3.8 版更改: 这个
writexml()
方法现在保留用户指定的属性顺序。
- Node.toxml(encoding=None, standalone=None)
返回包含由DOM节点表示的XML的字符串或字节字符串。
用一个明确的 encoding 1 参数,结果是指定编码的字节字符串。没有 encoding 参数,结果是Unicode字符串,结果字符串中的XML声明未指定编码。用UTF-8以外的编码对该字符串进行编码可能不正确,因为UTF-8是XML的默认编码。
这个 独立的 参数的行为与
writexml()
.在 3.8 版更改: 这个
toxml()
方法现在保留用户指定的属性顺序。
- Node.toprettyxml(indent='\t', newl='\n', encoding=None, standalone=None)
返回文档的精美打印版本。 缩进 指定缩进字符串并默认为制表符; newl 指定每行末尾发出的字符串,默认为
\n
.这个 encoding 参数的行为类似于
toxml()
.这个 独立的 参数的行为与
writexml()
.在 3.8 版更改: 这个
toprettyxml()
方法现在保留用户指定的属性顺序。
DOM示例
这个示例程序是一个相当现实的简单程序示例。在这个特定的例子中,我们并没有充分利用DOM的灵活性。
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 2特性(主要是命名空间特性)兼容的dom 1.0。
在python中使用dom接口是直接的。以下映射规则适用:
通过实例对象访问接口。应用程序不应该实例化类本身;它们应该使用
Document
对象。派生接口支持来自基本接口的所有操作(和属性),以及任何新操作。操作用作方法。因为DOM只使用
in
参数,参数按正常顺序传递(从左到右)。没有可选参数。void
操作返回None
.IDL属性映射到实例属性。为了与用于python的omg idl语言映射兼容,属性
foo
也可以通过访问器方法访问_get_foo()
和_set_foo()
.readonly
属性不能更改;这在运行时不强制执行。类型
short int
,unsigned int
,unsigned long long
和boolean
所有映射到python integer对象。类型
DOMString
映射到python字符串。xml.dom.minidom
支持字节或字符串,但通常会生成字符串。类型的值DOMString
也可能是None
允许使用IDL的位置null
W3C中的DOM规范值。const
声明映射到各自范围内的变量(例如xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE
)不可更改。DOMException
中当前不支持xml.dom.minidom
. 相反,xml.dom.minidom
使用标准的python异常,例如TypeError
和AttributeError
.NodeList
对象是使用Python的内置列表类型实现的。这些对象提供了在DOM规范中定义的接口,但是对于早期版本的Python,它们不支持官方API。然而,它们比W3C建议中定义的接口更“ Python 式”。
以下接口在中没有实现 xml.dom.minidom
:
DOMTimeStamp
EntityReference
其中大部分反映了XML文档中的信息,而这些信息对于大多数DOM用户来说不是通用的实用工具。
脚注
- 1
XML输出中包含的编码名称应符合适当的标准。例如,“utf-8”是有效的,但“utf8”在XML文档的声明中无效,即使Python接受它作为编码名称。请参阅https://www.w3.org/tr/2006/rec-xml11-20060816/nt encodingdecl和https://www.iana.org/assignments/character-sets/character-sets.xhtml。