– 最小DOM实现 – 结构化标记处理工具(Python教程)(参考资料)
xml.dom.minidom
– 最小的DOM实现
源代码: Lib / xml / dom / minidom.py
xml.dom.minidom
是Document ObjectModel接口的最小实现,其API类似于其他语言。它旨在比完整的DOM更简单,也更小。不熟悉DOM的用户应该考虑使用xml.etree.ElementTree
代替他们进行XML处理的模块.
警告
xml.dom.minidom
模块不能安全地防止恶意构造的数据。如果您需要解析不受信任的orunauthenticated数据,请参阅XML漏洞.
DOM应用程序通常首先将一些XML解析为DOM。用xml.dom.minidom
,这是通过解析函数完成的:
from xml.dom.minidom import parse, parseStringdom1 = parse("c:\\temp\\mydata.xml") # parse an XML file by namedatasource = open("c:\\temp\\mydata.xml")dom2 = parse(datasource) # parse an open filedom3 = parseString("<myxml>Some data<empty/> some more data</myxml>")
parse()
函数可以采用文件名或打开的文件对象.
xml.dom.minidom.
parse
(filename_or_file, parser=None, bufsize=None)-
从给定的输入返回
Document
。filename_or_file可以是文件名,也可以是文件类对象。parser如果给定,则必须是SAX2parser对象。此函数将更改解析器的文档处理程序并激活名称空间支持;其他解析器配置(如设置实体解析器)必须事先完成.
如果你有一个字符串中的XML,你可以使用parseString()
functioninstead:
xml.dom.minidom.
parseString
(string, parser=None)-
返回
Document
代表string。这个方法创建一个io.StringIO
字符串的对象并将其传递给parse()
.
两个函数都返回一个Document
对象,表示文档的内容.
parse()
和parseString()
函数do是将XMLparser与“DOM构建器”连接起来,该构建器可以接受来自任何SAX解析器的解析事件并将它们转换为DOM树。函数的名称可能会产生误导,但在学习接口时很容易掌握。在这些函数返回之前,文档的解析将完成;只是这些功能本身不提供解析器实现.
你也可以创建一个Document
通过在“DOMImplementation”对象上调用方法。您可以通过调用getDOMImplementation()
包中的xml.dom
函数或xml.dom.minidom
模块来获取此对象。一旦你有了Document
,就可以向它添加子节点来填充DOM:
from xml.dom.minidom import getDOMImplementationimpl = getDOMImplementation()newdoc = impl.createDocument(None, "some_tag", None)top_element = newdoc.documentElementtext = 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的垃圾收集器会很好地处理树中的对象.
DOM对象
用于Python的DOM API的定义是作为xml.dom
模块文档的一部分给出的。本节列出了API与xml.dom.minidom
.
Node.
unlink
()之间的差异-
打破DOM中的内部引用,以便在没有循环GC的情况下对Python进行垃圾回收。即使循环GC可用,使用这可以使更多的内存更快可用,所以在不再需要DOMobjects时立即调用它是很好的做法。这只需要在上调用
Document
对象,但可以在子节点上调用以丢弃该节点的子节点.您可以通过使用
with
语句来避免显式调用此方法。以下代码将自动取消链接dom退出with
块时:with xml.dom.minidom.parse(datasource) as dom: ... # Work with dom.
Node.
writexml
(writer, indent=””, addindent=””, newl=””)-
将XML写入writer对象。作者应该有一个
write()
methodwhich匹配文件对象接口的方法。indent参数是当前节点的压缩。addindent参数是用于当前子节点的incrementalIdentation。newl参数指定用于终止换行的字符串.对于
Document
节点,可以使用附加的关键字参数encoding来指定编码字段XML header.
Node.
toxml
(encoding=None)-
有明确的encoding [1]参数,结果是指定编码中的字节串。没有encoding参数,结果是一个Unicode字符串,结果字符串中的XML声明没有指定编码。使用UTF-8以外的编码对此字符串进行编码可能不正确,因为UTF-8是XML的默认编码.
Node.
toprettyxml
(indent=”\t”, newl=”\n”, encoding=None)-
返回一个漂亮的打印该文件的版本。indent指定压缩字符串并默认为制表符;newl指定每行末尾的stringemitted并默认为
\n
.encoding参数的行为类似于
toxml()
.
DOM的对应参数示例
这个示例程序是一个简单程序的一个相当现实的例子。在这个特例中,我们没有太多利用DOM的灵活性
import xml.dom.minidomdocument = """\<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 IDLlanguage映射,也可以通过访问方法访问
foo
属性_get_foo()
和_set_foo()
.readonly
属性不得更改;这不是在运行时强制执行的. - 类型
short int
,unsigned int
,unsigned long long
,和boolean
全部映射到Python整数对象. - 类型
DOMString
映射到Python字符串。xml.dom.minidom
支持字节或字符串,但通常会产生字符串。类型为DOMString
的值也可能是None
允许IDLnull
值由来自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。然而,它们比W3Crecommendations中定义的接口更加“Pythonic”.
以下接口在xml.dom.minidom
:
DOMTimeStamp
DocumentType
DOMImplementation
CharacterData
CDATASection
Notation
Entity
EntityReference
DocumentFragment
其中大部分都反映了XML文档中对大多数DOM用户不具备通用性的信息.
脚注
[1] | XML输出中包含的编码名称应符合适当的标准。例如,“UTF-8”有效,但“UTF8”在XML文档的声明中无效,即使Python将其作为编码名称接受。参见https://www.w3.org/TR/2006/REC-xml11-20060816 /#NT-EncodingDecland https://www.iana.org/assignments/character-sets/character-sets.xhtml. |