xml.dom
xml.dom - 文档对象模型API
2.0版本中的新功能。
文档对象模型或“DOM”是万维网联盟(W3C)的跨语言API,用于访问和修改XML文档。DOM实现将XML文档呈现为树结构,或者允许客户端代码从头构建这样的结构。然后通过提供众所周知的接口的一组对象来访问该结构。
DOM对随机访问应用程序非常有用。SAX只允许您一次查看文档的一个位。如果您正在查看一个SAX元素,则无法访问其他元素。如果您正在查看文本节点,则无法访问包含元素。当你编写一个SAX应用程序时,你需要跟踪自己代码中某个地方的程序在文档中的位置。SAX不会为你做。另外,如果你需要在XML文档中向前看,你只是运气不好。
某些应用程序在事件驱动模型中无法访问树是根本不可能的。当然,你可以在SAX事件中自己构建某种树,但是DOM允许你避免编写代码。DOM是XML数据的标准树表示。
文档对象模型由W3C分阶段定义,或者在其术语中定义为“级别”。API的Python映射基本上基于DOM Level 2推荐。
通常,DOM应用程序首先将一些XML解析为DOM。 如何实现这一点完全没有被DOM Level 1覆盖,而Level 2只提供了有限的改进:有一个DOMImplementation对象类,它提供了对文档创建方法的访问,但没有办法访问XML读取器/解析器/文档构建器 独立于实现的方式。 在没有现有Document对象的情况下,也没有明确定义的方式来访问这些方法。 在Python中,每个DOM实现将提供一个函数getDOMImplementation()。 DOM Level 3添加了一个Load / Store规范,该规范为读者定义了一个接口,但是这在Python标准库中尚不可用。
一旦有了DOM文档对象,就可以通过其属性和方法访问XML文档的各个部分。这些属性在DOM规范中定义; 这部分参考手册描述了Python中规范的解释。
W3C提供的规范定义了用于Java,ECMAScript和OMG IDL的DOM API。这里定义的Python映射很大程度上基于IDL版本的规范,但不需要严格的遵从(尽管实现可以自由支持来自IDL的严格映射)。有关映射要求的详细讨论,请参阅一致性部分。
扩展内容
文档对象模型(DOM)Level 2规范 Python DOM API所基于的W3C推荐标准。文档对象模型(DOM)1级规范 W3C推荐的DOM支持xml.dom.minidom
。Python语言映射规范这指定了从OMG IDL到Python的映射。
1.模块内容
将xml.dom
包含以下功能:
xml.dom.registerDOMImplementation(name, factory)
注册工厂
名称
为功能名称
。工厂
函数应该返回一个实现DOMImplementation
接口的对象。工厂
函数可以每次都返回相同的对象,或者针对每次调用返回一个新对象,以适合特定的实现(例如,如果该实现支持一些定制)。
xml.dom.getDOMImplementation([name[, features]])
返回一个合适的DOM实现。 该名称是众所周知的,DOM实现的模块名称或None。 如果不是None,则导入相应的模块,并在导入成功时返回DOMImplementation对象。 如果未给出名称,并且已设置环境变量PYTHON_DOM,则使用此变量查找实现。
如果没有给出名称,这将检查可用实现以找到具有所需功能集的实现。如果没有找到实现,请举一个ImportError
。(feature, version)
要素列表必须是hasFeature()
在可用DOMImplementation
对象上传递给方法的一系列对。
还提供了一些便利常数:
xml.dom.EMPTY_NAMESPACE
用于指示没有名称空间与DOM中的节点关联的值。 这通常可以作为节点的namespaceURI找到,或者用作名称空间特定方法的namespaceURI参数。
2.2版本中的新功能。
xml.dom.XML_NAMESPACE
与保留前缀关联的名称空间URI xml
,由XML中的Namespaces定义(第4节)。
2.2版本中的新功能。
xml.dom.XMLNS_NAMESPACE
由文档对象模型(DOM)Level 2 Core Specification(第1.1.8节)定义的名称空间声明的名称空间URI 。
2.2版本中的新功能。
xml.dom.XHTML_NAMESPACE
由XHTML 1.0定义的XHTML名称空间的URI :可扩展超文本标记语言(3.1.1节)。
2.2版本中的新功能。
另外,xml.dom包含一个基本的Node类和DOM异常类。 这个模块提供的Node类没有实现DOM规范定义的任何方法或属性; 具体的DOM实现必须提供这些。 作为此模块一部分提供的Node类确实提供了用于具体Node对象上的nodeType属性的常量; 它们位于类内而不是模块级,以符合DOM规范。
2. DOM中的对象
DOM的权威性文档是W3C的DOM规范。
请注意,DOM属性也可以作为节点来操作,而不是简单的字符串。然而,你必须这样做是非常罕见的,所以这种用法还没有记录。
接口 | 分块 | 目的 |
---|---|---|
DOMImplementation | DOMImplementation对象 | 接口的底层实现。 |
Node | 节点对象 | 文档中大多数对象的基本接口。 |
NodeList | NodeList对象 | 一系列节点的接口。 |
DocumentType | DocumentType对象 | 关于处理文档所需声明的信息。 |
Document | 文档对象 | 表示整个文档的对象。 |
Element | 元素对象 | 文档层次结构中的元素节点。 |
ATTR | 属性对象 | 元素节点上的属性值节点。 |
Comment | 评论对象 | 在源文档中表示评论。 |
Text | 文本和CDATASection对象 | 包含文档中文本内容的节点。 |
ProcessingInstruction | ProcessingInstruction对象 | 处理指令表示。 |
附加部分描述了在Python中使用DOM定义的异常。
2.1。DOMImplementation对象
DOMImplementation接口为应用程序提供了一种方法来确定他们正在使用的DOM中特定功能的可用性。 DOM Level 2增加了使用DOMImplementation创建新的Document和DocumentType对象的功能。
DOMImplementation.hasFeature(feature, version)
如果实现了一对字符串功能
和版本
标识的功能
,则返回true 。
DOMImplementation.createDocument(namespaceUri, qualifiedName, doctype)
使用具有给定namespaceUri和qualifiedName的子元素对象返回一个新的Document对象(DOM的根)。 doctype必须是由createDocumentType()或None创建的DocumentType对象。 在Python DOM API中,前两个参数也可以是None,以表示不要创建Element子元素。
DOMImplementation.createDocumentType(qualifiedName, publicId, systemId)
返回一个DocumentType
封装给定的qualifiedName
,publicId
和systemId
字符串的新对象,表示包含在XML文档类型声明中的信息。
2.2 节点对象
XML文档的所有组件都是Node的子类。
Node.nodeType
表示节点类型的整数。 这些类型的符号常量位于Node对象上:ELEMENT_NODE,ATTRIBUTE_NODE,TEXT_NODE,CDATA_SECTION_NODE,ENTITY_NODE,PROCESSING_INSTRUCTION_NODE,COMMENT_NODE,DOCUMENT_NODE,DOCUMENT_TYPE_NODE,NOTATION_NODE。 这是一个只读属性。
Node.parentNode
当前节点的父节点,或文档节点的None。 该值始终是一个Node对象或None。 对于元素节点,这将是父元素,除了根元素,在这种情况下它将是Document对象。 对于Attr节点,这总是无。 这是一个只读属性。
Node.attributes
一个NamedNodeMap
属性对象。只有元素才具有实际的价值; 其他人提供None
这个属性。这是一个只读属性。
Node.previousSibling
紧跟在同一父节点之前的节点。例如,在自身
元素的开始标记之前有一个结束标记的元素。当然,XML文档不仅仅包含元素,所以以前的兄弟可以是文本,评论或其他东西。如果此节点是父项的第一个子项,则此属性将为None
。这是一个只读属性。
Node.nextSibling
紧跟在这个父节点之后的节点。另见previousSibling
。如果这是父项的最后一个子项,则此属性将为None
。这是一个只读属性。
Node.childNodes
此节点中包含的节点列表。这是一个只读属性。
Node.firstChild
节点的第一个孩子,如果有的话,或者None
。这是一个只读属性。
Node.lastChild
节点的最后一个子节点,如果有的话,或者None
。这是一个只读属性。
Node.localName
如果有冒号,冒号后面的部分是冒号,否则整个tagName。 该值是一个字符串。
Node.prefix
tagName在冒号前面的部分(如果有),否则为空字符串。 该值是一个字符串,或None。
Node.namespaceURI
与元素名称关联的名称空间。这将是一个字符串或None
。这是一个只读属性。
Node.nodeName
这对每种节点类型都有不同的含义; 有关详细信息,请参阅DOM规范。 您始终可以从另一个属性获取您在此处获得的信息,例如元素的tagName属性或属性的name属性。 对于所有节点类型,此属性的值将是一个字符串或None。 这是一个只读属性。
Node.nodeValue
这对每种节点类型都有不同的含义; 有关详细信息,请参阅DOM规范。情况类似于nodeName
。该值是一个字符串或None
。
Node.hasAttributes()
如果节点具有任何属性,则返回true。
Node.hasChildNodes()
如果节点有任何子节点,则返回true。
Node.isSameNode(other)
如果other
引用与此节点相同的节点,则返回true 。这对于使用任何类型的代理体系结构的DOM实现特别有用(因为多个对象可以引用同一个节点)。
注意
这是基于建议的DOM Level 3 API,它仍处于“工作草案”阶段,但这个特定的界面似乎没有争议。来自W3C的改变不一定会影响Python DOM接口中的这种方法(尽管任何新的W3C API也会被支持)。
Node.appendChild(newChild)
将新的子节点添加到子节点列表末尾的此节点,并返回newChild
。如果节点已经在树中,它将首先被移除。
Node.insertBefore(newChild, refChild)
在现有的子节点之前插入一个新的孩子节点。 它必须是refChild是这个节点的子节点的情况; 如果不是,则引发ValueError。 返回newChild返回。 如果refChild为None,它将在子列表的末尾插入newChild。
Node.removeChild(oldChild)
删除一个子节点。 oldChild必须是该节点的子节点; 如果不是,则引发ValueError。 oldChild成功返回。 如果oldChild不会进一步使用,则应调用其unlink()方法。
Node.replaceChild(newChild, oldChild)
用新节点替换现有节点。oldChild
必须是这个节点的子节点; 如果没有,则会提出ValueError
。
Node.normalize()
加入相邻的文本节点,以便所有文本段都作为单个Text
实例存储。这为许多应用程序简化了从DOM树处理文本。
2.1版本中的新功能。
Node.cloneNode(deep)
克隆这个节点。设置deep
意味着克隆所有子节点。这将返回克隆。
2.3 NodeList对象
NodeList表示一系列节点。 这些对象在DOM核心推荐中以两种方式使用:一个Element对象提供一个作为其子节点列表,Node的getElementsByTagName()和getElementsByTagNameNS()方法返回具有此接口的对象以表示查询结果。
DOM Level 2建议为这些对象定义了一个方法和一个属性:
NodeList.item(i)
如果还有一个,则返回序列中的第i
项None
。指数i
不得小于零或大于或等于序列的长度。
NodeList.length
序列中的节点数量。
另外,Python DOM接口要求提供一些额外的支持,以允许NodeList对象用作Python序列。 所有的NodeList实现都必须包含对__len __()和__getitem __()的支持; 这允许迭代NodeList中的for语句并正确支持len()内置函数。
如果一个DOM实现支持文档的修改,那么NodeList
实现也必须支持__setitem__()
和__delitem__()
方法。
2.4 DocumentType对象
有关由文档声明的符号和实体的信息(包括解析器使用它并可以提供信息的外部子集)可从DocumentType对象中获得。 文档的DocumentType可以从Document对象的doctype属性中获得; 如果文档没有DOCTYPE声明,则文档的doctype属性将设置为None,而不是此接口的实例。
DocumentType
是专业化的Node
,并增加了以下属性:
DocumentType.publicId
文档类型定义的外部子集的公共标识符。这将是一个字符串或None
。
DocumentType.systemId
文档类型定义的外部子集的系统标识符。这将作为一个字符串的URI,或None
。
DocumentType.internalSubset
从文档中提供完整内部子集的字符串。这不包括包含子集的括号。如果文档没有内部子集,应该是None
。
DocumentType.name
DOCTYPE
声明中给出的根元素的名称(如果存在)。
DocumentType.entities
这是一个给出外部实体定义的NamedNodeMap。 对于不止一次定义的实体名称,只提供第一个定义(其他则根据XML建议的要求被忽略)。 如果信息不是由解析器提供的,或者没有定义实体,则这可能是None。
DocumentType.notations
这是一个NamedNodeMap,给出了符号的定义。 对于不止一次定义的记法名称,只提供第一个定义(其他则根据XML建议的要求而被忽略)。 如果信息不是由解析器提供的,或者没有定义符号,则这可能是None。
2.5 文档对象
Document
表示整个XML文档,包括其组成元素,属性,处理指令,注释等。请记住它从中继承属性Node
。
Document.documentElement
文档的唯一根元素。
Document.createElement(tagName)
创建并返回一个新的元素节点。 元素在创建时未插入到文档中。 您需要使用其他方法之一(如insertBefore()或appendChild())来显式插入它。
Document.createElementNS(namespaceURI, tagName)
用命名空间创建并返回一个新元素。 tagName可能有一个前缀。 元素在创建时未插入到文档中。 您需要使用其他方法之一(如insertBefore()或appendChild())来显式插入它。
Document.createTextNode(data)
创建并返回包含作为参数传递的数据的文本节点。与其他创建方法一样,这个方法不会将节点插入树中。
Document.createComment(data)
创建并返回包含作为参数传递的数据的注释节点。与其他创建方法一样,这个方法不会将节点插入树中。
Document.createProcessingInstruction(target, data)
创建并返回包含作为参数传递的目标
和数据
的处理指令节点。与其他创建方法一样,这个方法不会将节点插入树中。
Document.createAttribute(name)
创建并返回一个属性节点。 此方法不会将属性节点与任何特定元素相关联。 您必须在适当的Element对象上使用setAttributeNode()来使用新创建的属性实例。
Document.createAttributeNS(namespaceURI, qualifiedName)
用命名空间创建并返回一个属性节点。 tagName可能有一个前缀。 此方法不会将属性节点与任何特定元素相关联。 您必须在适当的Element对象上使用setAttributeNode()来使用新创建的属性实例。
Document.getElementsByTagName(tagName)
搜索所有具有特定元素类型名称的后代(直接子代,子代孩子等)。
Document.getElementsByTagNameNS(namespaceURI, localName)
使用特定的命名空间URI和本地名搜索所有后代(直接的子节点,子节点的子节点等)。localname是前缀后的名称空间的一部分。
2.6 元素对象
Element
是node的一个子类,所以继承了该类的所有属性。
Element.tagName
元素类型名称。在使用命名空间的文档中,它可能有冒号。该值是一个字符串。
Element.getElementsByTagName(tagName)
与Document
类中的等同方法类似。
Element.getElementsByTagNameNS(namespaceURI, localName)
与Document
类中的等同方法相同。
Element.hasAttribute(name)
如果元素具有按名称
命名的属性,则返回true 。
Element.hasAttributeNS(namespaceURI, localName)
如果元素具有由namespaceURI
和localName
命名的属性,则返回true 。
Element.getAttribute(name)
以字符串形式返回按名称
命名的属性的值。如果不存在这样的属性,则返回空字符串,就好像该属性没有值。
Element.getAttributeNode(attrname)
返回Attr
由attrname
命名的属性的节点。
Element.getAttributeNS(namespaceURI, localName)
以字符串形式返回由namespaceURI
和localName
命名的属性的值。如果不存在这样的属性,则返回空字符串,就好像该属性没有值。
Element.getAttributeNodeNS(namespaceURI, localName)
在给定namespaceURI
和localName的情况下
,将属性值作为节点返回。
Element.removeAttribute(name)
按名称删除属性。如果没有匹配的属性,则引发NotFoundErr
。
Element.removeAttributeNode(oldAttr)
如果存在,请从属性列表中删除并返回oldAttr
。如果oldAttr
不存在,则提出NotFoundErr
。
Element.removeAttributeNS(namespaceURI, localName)
按名称删除属性。请注意,它使用localName而不是qname。如果没有匹配属性,则不会引发异常。
Element.setAttribute(name, value)
从字符串中设置一个属性值。
Element.setAttributeNode(newAttr)
将新的属性节点添加到元素,如果name
属性匹配,则在必要时替换现有的属性。如果发生替换,则将返回旧的属性节点。如果newAttr
已被使用,InuseAttributeErr
将会被提出。
Element.setAttributeNodeNS(newAttr)
添加一个新的属性节点到元素中,如果namespaceURI
和localName
属性匹配,则在必要时替换现有的属性。如果发生替换,则将返回旧的属性节点。如果newAttr
已被使用,InuseAttributeErr
将会被提出。
Element.setAttributeNS(namespaceURI, qname, value)
给定一个namespaceURI
和一个qname
,从一个字符串中设置一个属性值。请注意,qname
是整个属性名称。这与以上不同。
2.7 属性对象
Attr
从Node
中继承,所以继承了它的所有属性。
Attr.name
属性名称。在使用命名空间的文档中,它可能包含冒号。
Attr.localName
如果有冒号,冒号后面的部分名称,否则为整个名称。这是一个只读属性。
Attr.prefix
冒号前面的部分名称,如果有的话,否则为空字符串。
Attr.value
属性的文本值。这是该nodeValue
属性的同义词。
2.8 命名的节点映射对象
NamedNodeMap
并没有
继承Node
。
NamedNodeMap.length
属性列表的长度。
NamedNodeMap.item(index)
返回具有特定索引的属性。您获取属性的顺序是任意的,但对于DOM的生命周期将保持一致。每个项目是一个属性节点。通过value
属性获取它的值。
也有实验方法给这个类更多的映射行为。您可以使用它们,也可以getAttribute*()
在Element
对象上使用标准化的方法族。
2.9 评论对象
Comment
代表XML文档中的评论。它是子类Node
,但不能有子节点。
Comment.data
评论的内容为一个字符串。该属性包含前导<!--和尾随之间的所有字符-->,但不包括它们。
2.10。文本和CDATASection对象
该Text
接口表示在XML文档中的文本。如果解析器和DOM实现支持DOM的XML扩展,那么封装在CDATA标记节中的部分文本将存储在CDATASection
对象中。这两个接口是相同的,但为nodeType
属性提供不同的值。
这些接口扩展了Node
接口。他们不能有子节点。
Text.data
文本节点的内容为字符串。
注意
CDATASection节点的使用并不表示该节点表示一个完整的CDATA标记部分,只是该节点的内容是CDATA部分的一部分。 单个CDATA部分可以由文档树中的多个节点表示。 无法确定两个相邻的CDATASection节点是否代表不同的CDATA标记节。
2.11 ProcessingInstruction对象
表示XML文档中的处理指令; 这从Node
接口继承并且不能有子节点。
ProcessingInstruction.target
处理指令的内容直至第一个空白字符。这是一个只读属性。
ProcessingInstruction.data
处理指令的内容跟在第一个空白字符之后。
2.12 Exceptions
2.1版本中的新功能。
DOM Level 2建议定义了一个单例,DOMException和一些允许应用程序确定发生的错误的常量。 DOMException实例携带一个代码属性,为特定的异常提供适当的值。
Python DOM接口提供了常量,但也扩展了一组异常,以便DOM中定义的每个异常代码都存在特定的异常。这些实现必须引发适当的特定异常,每个异常都带有相应的code
属性值。
exception xml.dom.DOMException
用于所有特定DOM异常的基本异常类。这个异常类不能直接实例化。
exception xml.dom.DomstringSizeErr
当指定范围的文本不适合字符串时引发。这不是已知用于Python DOM实现,但可能从未使用Python编写的DOM实现中获得。
exception xml.dom.HierarchyRequestErr
当尝试插入不允许节点类型的节点时引发。
exception xml.dom.IndexSizeErr
当方法的索引或大小参数为负值或超出允许值时引发。
exception xml.dom.InuseAttributeErr
当尝试插入已存在于文档中其他位置的Attr节点时引发。
exception xml.dom.InvalidAccessErr
如果基础对象不支持参数或操作,则引发。
exception xml.dom.InvalidCharacterErr
如果字符串参数包含在XML 1.0建议中使用的上下文中不允许的字符,则会引发此异常。例如,尝试Element
在元素类型名称中创建具有空格的节点会导致此错误的发生。
exception xml.dom.InvalidModificationErr
当尝试修改节点的类型时引发。
exception xml.dom.InvalidStateErr
当尝试使用未定义或不再可用的对象时引发。
exception xml.dom.NamespaceErr
如果尝试以XML建议中的名称空间不允许的方式更改任何对象,则会引发此异常。
exception xml.dom.NotFoundErr
在引用的上下文中不存在节点时异常。 例如,如果传入的节点在地图中不存在,NamedNodeMap.removeNamedItem()将引发此操作。
exception xml.dom.NotSupportedErr
当实现不支持请求类型的对象或操作时引发。
exception xml.dom.NoDataAllowedErr
如果为不支持数据的节点指定了数据,则会引发此问题。
exception xml.dom.NoModificationAllowedErr
引发尝试修改不允许修改的对象(例如对于只读节点)。
exception xml.dom.SyntaxErr
当指定了无效或非法字符串时引发。
exception xml.dom.WrongDocumentErr
当节点插入到与当前所属不同的文档中时引发,并且实现不支持将节点从一个文档迁移到另一个文档。
DOM建议中定义的异常代码根据此表映射到上述异常:
常量 | 例外 |
---|---|
DOMSTRING_SIZE_ERR | DomstringSizeErr |
HIERARCHY_REQUEST_ERR | HierarchyRequestErr |
INDEX_SIZE_ERR | IndexSizeErr |
INUSE_ATTRIBUTE_ERR | InuseAttributeErr |
INVALID_ACCESS_ERR | InvalidAccessErr |
INVALID_CHARACTER_ERR | InvalidCharacterErr |
INVALID_MODIFICATION_ERR | InvalidModificationErr |
INVALID_STATE_ERR | InvalidStateErr |
NAMESPACE_ERR | NamespaceErr |
NOT_FOUND_ERR | NotFoundErr |
NOT_SUPPORTED_ERR | NotSupportedErr |
NO_DATA_ALLOWED_ERR | NoDataAllowedErr |
NO_MODIFICATION_ALLOWED_ERR | NoModificationAllowedErr |
SYNTAX_ERR | SyntaxErr |
WRONG_DOCUMENT_ERR | WrongDocumentErr |
3.一致性
本节介绍Python DOM API,W3C DOM推荐和Python的OMG IDL映射之间的一致性要求和关系。
3.1 类型映射
根据下表将DOM规范中使用的原始IDL类型映射到Python类型。
IDL类型 | Python类型 |
---|---|
布尔 | IntegerType(值为0或1) |
INT | IntegerType |
长整型 | IntegerType |
无符号整数 | IntegerType |
此外,DOMString
建议中定义的内容将映射到Python字符串或Unicode字符串。每当从DOM返回字符串时,应用程序应该能够处理Unicode。
IDL null
值被映射到None
,只要null
API允许,该值可以被实现接受或提供。
3.2 访问器方法
从OMG IDL到Python attribute
的映射以Java映射的方式为IDL 声明定义访问器函数。映射IDL声明
readonly attribute string someValue;
attribute string anotherValue;
产生三种存取器函数:一个“获取”方法someValue
(_get_someValue()
),和“获取”和“设置”为方法anotherValue
(_get_anotherValue()
和_set_anotherValue()
)。映射,尤其是不需要的IDL属性是访问正常的Python属性:object.someValue
是不是
工作需要,并且可能引发AttributeError
。
但是,Python DOM API 确实
需要正常的属性访问。这意味着由Python IDL编译器生成的典型代理不可能工作,并且如果通过CORBA访问DOM对象,则可能需要在客户端上包装对象。虽然这确实
需要对CORBA DOM客户端进行一些额外的考虑,但具有从Python使用DOM到CORBA的经验的实施者并不认为这是一个问题。所声明的属性readonly
可能不会限制所有DOM实现中的写入访问。
在Python DOM API中,访问函数不是必需的。如果提供,它们应该采用由Python IDL映射定义的形式,但这些方法被认为是不必要的,因为可以直接从Python访问这些属性。不应该为readonly
属性提供“设置”访问器。
IDL定义并未完全体现W3C DOM API的要求,例如某些对象的概念,如返回值为getElementsByTagName()
“live”。Python DOM API不需要实现来执行这些需求。