20.6. xml.dom - 文档对象模型API

源代码: Lib / xml / dom / __ init __。py

文档对象模型或“DOM”是来自万维网联盟(W3C)的用于访问和修改XML文档的跨语言API。DOM实现将XML文档呈现为树结构,或者允许客户端代码从头开始构建这样的结构。然后它通过一组提供众所周知的接口的对象来访问结构。

DOM对于随机访问应用非常有用。SAX只允许一次查看文档的一个位。如果你正在查看一个SAX元素,你没有访问另一个。如果查看文本节点,则不能访问包含元素。当您编写SAX应用程序时,您需要在您自己的代码中的某处记录您的程序在文档中的位置。SAX不会为你做。另外,如果你需要在XML文档中向前看,你只是运气不好。

一些应用程序在不能访问树的事件驱动模型中是不可能的。当然,你可以在SAX事件中自己构建一些树,但DOM允许你避免编写代码。DOM是XML数据的标准树表示。

文档对象模型正在由W3C逐步定义,或者在术语中的“级别”。API的Python映射基本上基于DOM Level 2推荐。

DOM应用程序通常首先将一些XML解析为DOM。DOM级别1完全不涉及这一点,并且级别2仅提供有限的改进:有一个DOMImplementation对象类,它提供对Document创建方法的访问,但是没有办法以独立于实现的方式访问XML读取器/解析器/文档构建器。在没有现有Document对象的情况下,也没有定义良好的方法来访问这些方法。在Python中,每个DOM实现都将提供一个函数getDOMImplementation()DOM Level 3添加了一个加载/存储规范,它定义了一个读取器的接口,但这在Python标准库中还不可用。

一旦有了DOM文档对象,就可以通过它的属性和方法访问XML文档的部分。这些属性在DOM规范中定义;这部分参考手册描述了Python中对规范的解释。

W3C提供的规范定义了Java,ECMAScript和OMG IDL的DOM API。这里定义的Python映射在很大程度上基于规范的IDL版本,但不需要严格的遵从性(尽管实现可以自由地支持来自IDL的严格映射)。有关映射要求的详细讨论,请参阅Conformance一节。

也可以看看

文档对象模型(DOM)2级规范
Python DOM API所基于的W3C推荐。
文档对象模型(DOM)1级规范
W3C对xml.dom.minidom支持的DOM的建议。
Python语言映射规范
这指定从OMG IDL到Python的映射。

20.6.1. Module Contents

xml.dom包含以下函数:

xml.dom.registerDOMImplementation(name, factory)

使用名称名称注册工厂功能。工厂函数应该返回一个实现DOMImplementation接口的对象。工厂函数可以每次返回相同的对象,或者对于每个调用一个新的对象,适合于特定的实现(例如,如果该实现支持一些定制)。

xml.dom.getDOMImplementation(name=None, features=())

返回一个合适的DOM实现。名称是众所周知的,DOM实现的模块名称,或None如果不是None,则导入相应的模块,并在导入成功时返回DOMImplementation对象。如果未指定名称,并且如果设置了环境变量 PYTHON_DOM,则使用此变量来查找实现。

如果没有给出名称,这将检查可用的实现以找到具有所需要的特征集合的实现。如果找不到实现,请引入ImportError功能列表必须是传递到hasFeature()(功能, 版本)方法对可用的DOMImplementation对象。

还提供了一些方便常数:

xml.dom.EMPTY_NAMESPACE

用于指示没有命名空间与DOM中的节点相关联的值。这通常作为节点的namespaceURI找到,或者用作命名空间特定方法的namespaceURI参数。

xml.dom.XML_NAMESPACE

XML中的命名空间(第4节)中定义的保留前缀xml相关联的命名空间URI。

xml.dom.XMLNS_NAMESPACE

命名空间声明的命名空间URI,由文档对象模型(DOM)2级核心规范(第1.1.8节)定义。

xml.dom.XHTML_NAMESPACE

XHTML 1.0:可扩展超文本标记语言(第3.1.1节)定义的XHTML命名空间的URI。

此外,xml.dom包含基本Node类和DOM异常类。该模块提供的Node类不实现DOM规范定义的任何方法或属性;具体的DOM实现必须提供那些。作为此模块一部分提供的Node类提供了用于具体Node对象上的nodeType属性的常量;它们位于类中,而不是位于模块级,以符合DOM规范。

20.6.2. Objects in the DOM

DOM的最终文档是来自W3C的DOM规范。

注意,DOM属性也可以作为节点而不是简单的字符串来操作。这是很少见的,你必须这样做,但是,因此这种用法还没有记录。

接口部分目的
DOMImplementationDOMImplementation Objects底层实现的接口。
NodeNode Objects文档中大多数对象的基本接口。
NodeListNodeList Objects节点序列的接口。
DocumentTypeDocumentType Objects有关处理文档所需的声明的信息。
DocumentDocument Objects表示整个文档的对象。
ElementElement Objects文档层次结构中的元素节点。
AttrAttr Objects元素节点上的属性值节点。
CommentComment Objects表示源文档中的注释。
TextText and CDATASection Objects包含文档中文本内容的节点。
ProcessingInstructionProcessingInstruction Objects处理指令表示。

附加部分描述了为在Python中使用DOM定义的异常。

20.6.2.1. DOMImplementation Objects

DOMImplementation接口为应用程序提供了一种确定其所使用的DOM中特定功能的可用性的方法。DOM Level 2添加了使用DOMImplementation创建新DocumentDocumentType对象的功能。

DOMImplementation.hasFeature(feature, version)

如果实现由字符串特征版本标识的功能,则返回true。

DOMImplementation.createDocument(namespaceUri, qualifiedName, doctype)

Return a new Document object (the root of the DOM), with a child Element object having the given namespaceUri and qualifiedName. doctype必须是由createDocumentType()None创建的DocumentType对象。在Python DOM API中,前两个参数也可以是None,以表示不要创建Element子元素。

DOMImplementation.createDocumentType(qualifiedName, publicId, systemId)

返回封装给定qualifiedNamepublicIdsystemId字符串的新DocumentType对象,一个XML文档类型声明。

20.6.2.2. Node Objects

XML文档的所有组件都是Node的子类。

Node.nodeType

表示节点类型的整数。Symbolic constants for the types are on the Node object: 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对于Element节点,这将是父元素,除了根元素,在这种情况下,它将是Document对象。对于Attr节点,这始终是None这是一个只读属性。

Node.attributes

属性对象的NamedNodeMap只有元素具有实际值;其他人为此属性提供None这是一个只读属性。

Node.previousSibling

紧接在此之前的节点具有相同的父节点。对于实例,具有结束标记的元素就在self元素的开始标记之前。当然,XML文档不仅仅是元素,所以前面的兄弟可以是文本,注释或其他东西。如果此节点是父节点的第一个子节点,此属性将为None这是一个只读属性。

Node.nextSibling

紧随此后的节点具有相同的父节点。另请参见previousSibling如果这是父级的最后一个子级,则此属性将为None这是一个只读属性。

Node.childNodes

此节点中包含的节点的列表。这是一个只读属性。

Node.firstChild

节点的第一个子节点,如果有,或None这是一个只读属性。

Node.lastChild

节点的最后一个子节点,如果有,或None这是一个只读属性。

Node.localName

tagName在冒号后面的部分(如果有冒号),否则为整个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)

如果其他指向与此节点相同的节点,则返回true。这对于使用任何类型的代理体系结构的DOM实现(因为多个对象可以引用同一个节点)特别有用。

注意

这是基于一个仍然在“工作草案”阶段提出的DOM 3级API,但这个特定的接口显示无争议。W3C中的更改不一定会影响Python DOM接口中的此方法(尽管也将支持任何新的W3C API)。

Node.appendChild(newChild)

在子节点列表末尾向此节点添加新的子节点,返回newChild如果节点已经在树中,则首先将其删除。

Node.insertBefore(newChild, refChild)

在现有子节点之前插入新的子节点。它必须是refChild是此节点的子节点的情况;如果不是,则引发ValueError返回newChild如果refChildNone,则会在子元素列表的末尾插入newChild

Node.removeChild(oldChild)

删除子节点。oldChild必须是此节点的子节点;如果不是,则引发ValueErroroldChild成功返​​回。如果oldChild不会被进一步使用,则应调用unlink()方法。

Node.replaceChild(newChild, oldChild)

将现有节点替换为新节点。必须是oldChild是此节点的子节点的情况;如果不是,则引发ValueError

Node.normalize()

连接相邻的文本节点,以便所有文本段都作为单个Text实例存储。这简化了从许多应用程序的DOM树处理文本。

Node.cloneNode(deep)

克隆此节点。设置意味着也克隆所有子节点。这将返回克隆。

20.6.2.3. NodeList Objects

NodeList表示节点序列。这些对象在DOM Core推荐中以两种方式使用:Element对象提供一个作为其子节点的列表,getElementsByTagName()getElementsByTagNameNS()方法Node返回具有此接口的对象以表示查询结果。

DOM Level 2建议为这些对象定义了一个方法和一个属性:

NodeList.item(i)

从序列中返回i项目(如果有),或None索引i不允许小于零或大于或等于序列的长度。

NodeList.length

序列中的节点数。

此外,Python DOM接口需要提供一些额外的支持,以允许将NodeList对象用作Python序列。All NodeList implementations must include support for __len__() and __getitem__(); this allows iteration over the NodeList in for statements and proper support for the len() built-in function.

如果DOM实现支持修改文档,则NodeList实现还必须支持__setitem__()__delitem__()方法。

20.6.2.4. DocumentType Objects

有关文档声明的符号和实体的信息(包括外部子集,如果解析器使用它并且可以提供信息)可从DocumentType对象获取。文档的DocumentType可从Document对象的doctype属性中获取;如果文档没有DOCTYPE声明,则文档的doctype属性将设置为None,而不是此界面的实例。

DocumentTypeNode的特殊化,并添加以下属性:

DocumentType.publicId

文档类型定义的外部子集的公共标识符。这将是一个字符串或None

DocumentType.systemId

文档类型定义的外部子集的系统标识符。这将是一个URI作为字符串,或None

DocumentType.internalSubset

从文档提供完整内部子集的字符串。这不包括括起子集的括号。如果文档没有内部子集,则应为None

DocumentType.name

DOCTYPE声明中指定的根元素的名称(如果存在)。

DocumentType.entities

这是一个提供外部实体定义的NamedNodeMap对于多次定义的实体名称,只提供第一个定义(根据XML建议的要求忽略其他定义)。如果信息未由解析器提供,或者如果未定义任何实体,则可以是None

DocumentType.notations

这是一个提供符号定义的NamedNodeMap对于不止一次定义的符号名称,仅提供第一个定义(根据XML建议的要求,忽略其他定义)。如果信息未由解析器提供,或者如果未定义符号,则可以是None

20.6.2.5. Document Objects

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是前缀后的命名空间的一部分。

20.6.2.6. Element Objects

ElementNode的子类,因此继承了该类的所有属性。

Element.tagName

元素类型名称。在使用命名空间的文档中,它可能有冒号。该值是一个字符串。

Element.getElementsByTagName(tagName)

Document类中的等效方法相同。

Element.getElementsByTagNameNS(namespaceURI, localName)

Document类中的等效方法相同。

Element.hasAttribute(name)

如果元素具有由name命名的属性,则返回true。

Element.hasAttributeNS(namespaceURI, localName)

如果元素具有由namespaceURIlocalName命名的属性,则返回true。

Element.getAttribute(name)

将由name命名的属性的值作为字符串返回。如果不存在此属性,则返回一个空字符串,就像该属性没有值一样。

Element.getAttributeNode(attrname)

返回attrname命名的属性的Attr节点。

Element.getAttributeNS(namespaceURI, localName)

namespaceURIlocalName命名的属性的值作为字符串返回。如果不存在此属性,则返回一个空字符串,就像该属性没有值一样。

Element.getAttributeNodeNS(namespaceURI, localName)

给定一个namespaceURIlocalName,返回一个属性值作为节点。

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)

向元素添加新的属性节点,如果namespaceURIlocalName属性匹配,则替换现有属性。如果发生替换,将返回旧的属性节点。如果newAttr已在使用,则会引发InuseAttributeErr

Element.setAttributeNS(namespaceURI, qname, value)

如果给定namespaceURIqname,请从字符串中设置属性值。注意,qname是整个属性名称。这与上面不同。

20.6.2.7. Attr Objects

Attr继承Node,因此继承其所有属性。

Attr.name

属性名称。在使用命名空间的文档中,可以包含冒号。

Attr.localName

冒号之后的名称部分,如果有一个,否则整个名称。这是一个只读属性。

Attr.prefix

冒号前面的名称部分,如果有一个,否则空字符串。

Attr.value

属性的文本值。这是nodeValue属性的同义词。

20.6.2.8. NamedNodeMap Objects

NamedNodeMap确实继承Node

NamedNodeMap.length

属性列表的长度。

NamedNodeMap.item(index)

返回具有特定索引的属性。你获得属性的顺序是任意的,但是对于DOM的生命是一致的。每个项目是一个属性节点。使用value属性获取其值。

还有实验方法给这个类更多的映射行为。您可以使用它们,也可以在Element对象上使用标准化的getAttribute*()方法系列。

20.6.2.9. Comment Objects

Comment表示XML文档中的注释。它是Node的子类,但不能有子节点。

Comment.data

注释的内容为字符串。该属性包含前导<!- -和尾随- ->之间的所有字符,不包括他们。

20.6.2.10. Text and CDATASection Objects

Text接口表示XML文档中的文本。如果解析器和DOM实现支持DOM的XML扩展,则在CDATA标记部分中包含的文本部分存储在CDATASection对象中。这两个接口相同,但为nodeType属性提供不同的值。

这些接口扩展Node接口。他们不能有子节点。

Text.data

文本节点的内容作为字符串。

注意

使用CDATASection节点不表示节点表示完整的CDATA标记部分,只是节点的内容是CDATA部分的一部分。单个CDATA段可以由文档树中的多于一个节点表示。没有办法确定两个相邻的CDATASection节点是否代表不同的CDATA标记部分。

20.6.2.11. ProcessingInstruction Objects

表示XML文档中的处理指令;这继承自Node接口,并且不能有子节点。

ProcessingInstruction.target

直到第一个空格字符的处理指令的内容。这是一个只读属性。

ProcessingInstruction.data

第一个空格字符后的处理指令的内容。

20.6.2.12. Exceptions

DOM级别2建议定义了一个异常DOMException和允许应用程序确定发生了什么类型的错误的多个常量。DOMException实例带有code属性,为特定异常提供适当的值。

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_ERRDomstringSizeErr
HIERARCHY_REQUEST_ERRHierarchyRequestErr
INDEX_SIZE_ERRIndexSizeErr
INUSE_ATTRIBUTE_ERRInuseAttributeErr
INVALID_ACCESS_ERRInvalidAccessErr
INVALID_CHARACTER_ERRInvalidCharacterErr
INVALID_MODIFICATION_ERRInvalidModificationErr
INVALID_STATE_ERRInvalidStateErr
NAMESPACE_ERRNamespaceErr
NOT_FOUND_ERRNotFoundErr
NOT_SUPPORTED_ERRNotSupportedErr
NO_DATA_ALLOWED_ERRNoDataAllowedErr
NO_MODIFICATION_ALLOWED_ERRNoModificationAllowedErr
SYNTAX_ERRSyntaxErr
WRONG_DOCUMENT_ERRWrongDocumentErr

20.6.3. Conformance

本节描述了Python DOM API,W3C DOM建议和Python的OMG IDL映射之间的一致性要求和关系。

20.6.3.1. Type Mapping

DOM规范中使用的IDL类型根据下表映射到Python类型。

IDL类型Python类型
booleanboolint
intint
long intint
无符号 intint
DOMStringstrbytes
nullNone

20.6.3.2. Accessor Methods

从OMG IDL到Python的映射以Java映射的方式定义了IDL attribute声明的访问器函数。映射IDL声明

readonly attribute string someValue;
         attribute string anotherValue;

产生三个存取器函数:someValue_get_someValue())的“get”方法以及anotherValue_get_anotherValue()_set_anotherValue())。特别地,该映射不要求IDL属性可以作为普通的Python属性访问:object.someValue工作所需的,并且可以引入AttributeError

Python DOM API,要求正常的属性访问工作。这意味着由Python IDL编译器生成的典型代理不太可能工作,如果通过CORBA访问DOM对象,则客户端可能需要包装器对象。虽然这需要一些额外的考虑对CORBA DOM客户端,有经验的使用DOM的CORBA从Python的实施者不认为这是一个问题。声明为readonly的属性可能不会限制所有DOM实施中的写访问。

在Python DOM API中,不需要访问器函数。如果提供,它们应该采用由Python IDL映射定义的形式,但是这些方法被认为不必要,因为属性可以直接从Python访问。不应为readonly属性提供“设置”访问器。

IDL定义不完全体现W3C DOM API的要求,例如某些对象的概念,例如getElementsByTagName()的返回值为“live”。Python DOM API不需要实现来实施这些要求。