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

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


文档对象模型,或称为“dom”,是来自万维网联盟(W3C)的跨语言API,用于访问和修改XML文档。DOM实现将XML文档表示为树结构,或者允许客户机代码从头构建这样的结构。然后,它通过一组提供了著名接口的对象来访问该结构。

对于随机访问应用程序,DOM非常有用。SAX一次只允许您查看一个文档位。如果您查看的是一个SAX元素,则无法访问另一个。如果查看的是文本节点,则无法访问包含元素。编写SAX应用程序时,需要在自己的代码中的某个地方跟踪程序在文档中的位置。萨克斯不会帮你的。另外,如果您需要在XML文档中向前看,那么您就是走运了。

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

W3C正在分阶段定义文档对象模型,或者在其术语中定义“级别”。API的python映射基本上基于DOM级别2的建议。

DOM应用程序通常首先将一些XML解析为一个DOM。dom级别1根本不包括如何完成这一点,级别2只提供了有限的改进:有一个 DOMImplementation 提供访问权限的对象类 Document 创建方法,但无法以独立于实现的方式访问XML阅读器/解析器/文档生成器。如果没有现有的 Document 对象。在Python中,每个DOM实现将提供一个函数 getDOMImplementation() . DOMLevel3添加了一个加载/存储规范,它定义了一个到读卡器的接口,但是在Python标准库中还没有这个接口。

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

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

参见

Document Object Model (DOM) Level 2 Specification

python dom API基于的W3C建议。

Document Object Model (DOM) Level 1 Specification

W3C对支持的DOM的建议 xml.dom.minidom .

Python Language Mapping Specification

这指定了从omg idl到python的映射。

模块内容

这个 xml.dom 包含以下功能:

xml.dom.registerDOMImplementation(name, factory)

注册 工厂 具有名称的函数 name . factory函数应返回实现 DOMImplementation 接口。factory函数每次都可以返回相同的对象,或者根据具体的实现(例如,如果该实现支持某些自定义)为每个调用返回一个新的对象。

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

返回适当的DOM实现。这个 name 是众所周知的,是DOM实现的模块名,或者 None . 如果不是 None ,导入相应的模块并返回 DOMImplementation 对象,如果导入成功。如果没有给出名称,并且如果环境变量 PYTHON_DOM 设置后,此变量用于查找实现。

如果没有给出名称,那么将检查可用的实现,以找到具有所需功能集的实现。如果找不到实现,则引发 ImportError .功能列表必须是 (feature, version) 传递给 hasFeature() 可用的方法 DOMImplementation 物体。

还提供了一些便利常数:

xml.dom.EMPTY_NAMESPACE

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

xml.dom.XML_NAMESPACE

与保留前缀关联的命名空间URI xml ,如由 Namespaces in XML (第4节)。

xml.dom.XMLNS_NAMESPACE

命名空间声明的命名空间URI,由定义 Document Object Model (DOM) Level 2 Core Specification (第1.1.8节)。

xml.dom.XHTML_NAMESPACE

xhtml命名空间的uri由 XHTML 1.0: The Extensible HyperText Markup Language (第3.1.1节)。

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

DOM中的对象

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

注意,DOM属性也可以作为节点而不是简单的字符串来操作。但是,您必须这样做是非常罕见的,所以这个用法还没有文档记录。

界面

截面

目的

DOMImplementation

注册实施对象

与基础实现的接口。

Node

节点对象

文档中大多数对象的基本接口。

NodeList

节点列表对象

一系列节点的接口。

DocumentType

文档类型对象

有关处理文档所需声明的信息。

Document

文档对象

表示整个文档的对象。

Element

元素对象

文档层次结构中的元素节点。

Attr

Atter对象

元素节点上的属性值节点。

Comment

注释对象

源文档中注释的表示。

Text

文本和CDataSection对象

包含文档中文本内容的节点。

ProcessingInstruction

处理指令对象

处理指令表示。

另一节描述了为在Python中使用DOM而定义的异常。

注册实施对象

这个 DOMImplementation 接口为应用程序提供了一种方法来确定它们正在使用的DOM中特定功能的可用性。DOM级别2添加了创建新的 DocumentDocumentType 对象使用 DOMImplementation 也。

DOMImplementation.hasFeature(feature, version)

返回 True 如果由一对字符串标识的特征 特征版本 实现。

DOMImplementation.createDocument(namespaceUri, qualifiedName, doctype)

返回一个新的 Document 对象(dom的根),具有子对象 Element 对象具有给定的 命名空间限定名 . 这个 文档类型 必须是 DocumentType 对象创建者 createDocumentType()None . 在python dom api中,前两个参数也可以是 None 为了表明不 Element 将创建子项。

DOMImplementation.createDocumentType(qualifiedName, publicId, systemId)

返回一个新的 DocumentType 对象,该对象封装给定的 限定名公共标识符系统ID 字符串,表示XML文档类型声明中包含的信息。

节点对象

XML文档的所有组件都是 Node .

Node.nodeType

表示节点类型的整数。类型的符号常量位于 Node 对象: ELEMENT_NODEATTRIBUTE_NODETEXT_NODECDATA_SECTION_NODEENTITY_NODEPROCESSING_INSTRUCTION_NODECOMMENT_NODEDOCUMENT_NODEDOCUMENT_TYPE_NODENOTATION_NODE . 这是只读属性。

Node.parentNode

当前节点的父节点,或 None 对于文档节点。值始终是 Node 对象或 None . 为了 Element 节点,这将是父元素,但根元素除外,在这种情况下,它将是 Document 对象。为了 Attr 节点,这始终是 None . 这是只读属性。

Node.attributes

A 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实现尤其有用(因为多个对象可以引用同一个节点)。

注解

这是基于一个提议的DOMLevel3API,该API仍处于“工作草案”阶段,但是这个特定的接口似乎没有争议。来自W3C的更改不一定会影响python dom接口中的这个方法(尽管也支持针对这个的任何新W3CAPI)。

Node.appendChild(newChild)

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

Node.insertBefore(newChild, refChild)

在现有子节点之前插入新的子节点。一定是这样 再培养 是此节点的子节点;如果不是, ValueError 提高了。 新生 返回。如果 再培养None 它插入 新生 在子项名单的最后。

Node.removeChild(oldChild)

删除子节点。 老子 必须是此节点的子节点;如果不是, ValueError 提高了。 老子 成功时返回。如果 老子 将不再使用,其 unlink() 应调用方法。

Node.replaceChild(newChild, oldChild)

用新节点替换现有节点。一定是这样 老子 是此节点的子节点;如果不是, ValueError 提高了。

Node.normalize()

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

Node.cloneNode(deep)

复制此节点。设置 deep 也就是说复制所有子节点。这将返回复制。

节点列表对象

A NodeList 表示节点序列。在DOM核心建议中,这些对象有两种用法:一种是 Element 对象提供一个作为其子节点列表,并且 getElementsByTagName()getElementsByTagNameNS() 方法 Node 返回具有此接口的对象以表示查询结果。

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

NodeList.item(i)

返回 i '序列中的第个项目(如果有),或 None . 指数 i 不允许小于零或大于或等于序列的长度。

NodeList.length

序列中的节点数。

另外,python dom接口要求提供一些额外的支持,以允许 NodeList 用作Python序列的对象。所有 NodeList 实现必须包括对 __len__()__getitem__() ;这允许在 NodeList 在里面 for 声明和适当的支持 len() 内置功能。

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

文档类型对象

有关文档声明的符号和实体的信息(包括外部子集,如果解析器使用它并可以提供信息),可以从 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 如果解析器没有提供信息,或者没有定义符号。

文档对象

A Document 表示整个XML文档,包括其组成元素、属性、处理指令、注释等。请记住,它从 Node .

Document.documentElement

文档的唯一根元素。

Document.createElement(tagName)

创建并返回一个新的元素节点。创建元素时不会将其插入到文档中。您需要使用其他方法(如 insertBefore()appendChild() .

Document.createElementNS(namespaceURI, tagName)

创建并返回带有命名空间的新元素。这个 标签名 可能有前缀。创建元素时不会将其插入到文档中。您需要使用其他方法(如 insertBefore()appendChild() .

Document.createTextNode(data)

创建并返回包含作为参数传递的数据的文本节点。与其他创建方法一样,此方法不会将节点插入树中。

Document.createComment(data)

创建并返回一个包含作为参数传递的数据的注释节点。与其他创建方法一样,此方法不会将节点插入树中。

Document.createProcessingInstruction(target, data)

创建并返回包含 目标data 作为参数传递。与其他创建方法一样,此方法不会将节点插入树中。

Document.createAttribute(name)

创建并返回属性节点。此方法不将属性节点与任何特定元素关联。你必须使用 setAttributeNode() 在适当的 Element 对象以使用新创建的属性实例。

Document.createAttributeNS(namespaceURI, qualifiedName)

创建并返回具有命名空间的属性节点。这个 标签名 可能有前缀。此方法不将属性节点与任何特定元素关联。你必须使用 setAttributeNode() 在适当的 Element 对象以使用新创建的属性实例。

Document.getElementsByTagName(tagName)

搜索具有特定元素类型名称的所有子代(直接子代、子代等)。

Document.getElementsByTagNameNS(namespaceURI, localName)

搜索具有特定命名空间URI和localname的所有子代(直接子代、子代等)。localname是名称空间中前缀后面的部分。

元素对象

Element 是的子类 Node ,因此继承该类的所有属性。

Element.tagName

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

Element.getElementsByTagName(tagName)

与中的等效方法相同 Document 类。

Element.getElementsByTagNameNS(namespaceURI, localName)

与中的等效方法相同 Document 类。

Element.hasAttribute(name)

返回 True 如果元素有一个名为 name .

Element.hasAttributeNS(namespaceURI, localName)

返回 True 如果元素有一个名为 命名空间地名 .

Element.getAttribute(name)

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

Element.getAttributeNode(attrname)

返回 Attr 由命名的属性的节点 吸引力 .

Element.getAttributeNS(namespaceURI, localName)

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

Element.getAttributeNodeNS(namespaceURI, localName)

将属性值作为节点返回,给定 命名空间地名 .

Element.removeAttribute(name)

按名称删除属性。如果没有匹配的属性,则 NotFoundErr 提高了。

Element.removeAttributeNode(oldAttr)

移除并返回 奥尔达特 从属性列表(如果存在)。如果 奥尔达特 不存在, NotFoundErr 提高了。

Element.removeAttributeNS(namespaceURI, localName)

按名称删除属性。请注意,它使用的是localname,而不是qname。如果没有匹配的属性,则不会引发异常。

Element.setAttribute(name, value)

从字符串设置属性值。

Element.setAttributeNode(newAttr)

向元素添加新的属性节点,如果需要,则替换现有属性 name 属性匹配。如果发生替换,将返回旧的属性节点。如果 奈瓦特 已经在使用中, InuseAttributeErr 将被引发。

Element.setAttributeNodeNS(newAttr)

向元素添加新的属性节点,如果需要,则替换现有属性 namespaceURIlocalName 属性匹配。如果发生替换,将返回旧的属性节点。如果 奈瓦特 已经在使用中, InuseAttributeErr 将被引发。

Element.setAttributeNS(namespaceURI, qname, value)

从字符串中设置属性值,给定 命名空间 和A QNEX . 注意,qname是整个属性名。这与上面的不同。

Atter对象

Attr 继承自 Node ,所以继承它的所有属性。

Attr.name

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

Attr.localName

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

Attr.prefix

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

Attr.value

属性的文本值。这是 nodeValue 属性。

名称节点映射对象

NamedNodeMapnot 继承自 Node .

NamedNodeMap.length

属性列表的长度。

NamedNodeMap.item(index)

返回具有特定索引的属性。获取属性的顺序是任意的,但在DOM的生命周期中是一致的。每个项目都是一个属性节点。使用 value 属性。

还有一些实验方法可以让这个类有更多的映射行为。您可以使用它们,也可以使用标准化的 getAttribute*() 方法家族 Element 物体。

注释对象

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

Comment.data

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

文本和CDataSection对象

这个 Text 接口表示XML文档中的文本。如果解析器和dom实现支持dom的XML扩展,则包含在标记了cdata的部分中的文本将存储在 CDATASection 物体。这两个接口是相同的,但为 nodeType 属性。

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

Text.data

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

注解

A的使用 CDATASection 节点并不表示该节点表示一个完整的标记了CDATA的节,只表示该节点的内容是CDATA节的一部分。在文档树中,单个CDATA节可以由多个节点表示。无法确定两个相邻的 CDATASection 节点表示不同的CDATA标记的部分。

处理指令对象

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

ProcessingInstruction.target

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

ProcessingInstruction.data

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

例外情况

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

如果试图以不允许的方式更改任何对象, Namespaces in 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

一致性

本节描述了python dom api、w3c dom建议和用于python的omg idl映射之间的一致性要求和关系。

类型映射

dom规范中使用的idl类型根据下表映射到python类型。

IDL型

Python 型

boolean

bool or int

int

int

long int

int

unsigned int

int

DOMString

str or bytes

null

None

存取方法

omg idl到python的映射定义了idl的访问函数 attribute 以Java映射的方式进行声明。映射IDL声明::

readonly attribute string someValue;
         attribute string anotherValue;

生成三个访问函数:的“get”方法 someValue (_get_someValue() )和“get”和“set”方法 anotherValue (_get_anotherValue()_set_anotherValue() )尤其是,映射不要求IDL属性可以作为普通的python属性进行访问: object.someValuenot 需要工作,并且可以提高 AttributeError .

但是,python dom API, does 要求正常的属性访问工作。这意味着由python idl编译器生成的典型代理不太可能工作,如果通过CORBA访问DOM对象,则可能需要在客户机上使用封装对象。虽然这确实需要对CORBADOM客户机进行一些额外的考虑,但是具有在Python的CORBA上使用DOM经验的实现者并不认为这是一个问题。声明的属性 readonly 不能限制所有DOM实现中的写入访问。

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

IDL定义没有完全体现W3CDOMAPI的要求,例如某些对象的概念,例如 getElementsByTagName() “活着”。python dom api不需要实现来强制执行这些需求。