1.01k likes | 1.21k Views
第九章 XML DOM. 9.1 概述 9.2 一个 DOM 示例 9.3 DOM 基础知识 9.4 DOM 常用接口 9.5 XML DOM 设计. 9.1 概述. DOM(Document Object Model ,文本对象模型 ) 是一组接口规范,为应用程序提供访问文本对象的方法和属性。 XML DOM 专门用于访问 XML 文档数据。
E N D
第九章 XML DOM 9.1 概述 9.2 一个DOM示例 9.3 DOM基础知识 9.4 DOM常用接口 9.5 XML DOM设计
9.1 概述 DOM(Document Object Model,文本对象模型)是一组接口规范,为应用程序提供访问文本对象的方法和属性。XML DOM专门用于访问XML文档数据。 DOM问世很早,已经出现了DOM Level 1、DOM Level 2、DOM Level 3。DOM Level 3(下文简称DOM3)包含三个内容: DOM内核、DOM加载和存储、有效性检验。 本章我们将讨论DOM内核,有关DOM加载和存储、有效性检验请参考相关文献。
9.2 一个DOM示例 为了便于理解XML的DOM编程,我们先考察一个简单的XML文档,然后设计如何用XML DOM访问该文档。 例9.1 考察例7.10的XML文档(本章中名为ch9-1.xml),设计其DOM程序。 此文档构成根元素files下多个file子元素file下有四个孩子name、type、date、size,这是一个简单的XML文档,它的结构如图9.1。
files ………… file file name type size date 图9.1 例7.10的XML文档树型结构图 9.2 一个DOM示例
9.2 一个DOM示例 访问它的DOM程序设计如下: 1<html> 2 <head><title>文件信息</title></head> 3 <body> 4 <script language="JavaScript" > 5 var xmlDom=new ActiveXObject("MSXML2.DOMDocument.4.0"); 6 xmlDom.async="false"; 7 xmlDom.load("ch9-1.xml"); 8 var xmlObj=xmlDom.documentElement.childNodes; 9 //显示根结点名称 10 document.write(xmlDom.documentElement.nodeName+"<br/>"); 11 //显示所有子结点名称和元素值 12 var xmlObj=xmlDom.documentElement.childNodes; 13 for(var i=0;i<xmlObj.length;i++) 14 { 15 document.write("| +-- "+xmlObj.item(i).nodeName+"<br/>");
9.2 一个DOM示例 16 if(xmlObj.item(i).hasChildNodes) 17 { 18 //到下一层 19 xmlSubNode=xmlObj.item(i).childNodes; 20 for(var j=0;j<xmlSubNode.length;j++) 21 { 22 document.write("| | +--"); 23 document.write(xmlSubNode.item(j).nodeName+":"); 24 document.write(xmlSubNode.item(j).text+"<br/>"); 25 } 26 } 27 } 28 </script> 29</body> 30</html>
图9.2 例9.1的DOM转换 9.2 一个DOM示例
9.2 一个DOM示例 该程序显示的文档结构如图9.2。程序分析如下: ①此程序借助HTML来显示,使用Java脚本语言编程。 ②4-28行为嵌入脚本。 ③5-7行,创建DOM对象xmlDom、用xmlDom.load方法加载XML文件。 ④7行,设置变量xmlObj,用xmlDom对象的属性documentElement把XML文档树根结点下的所有子结点赋值给xmlObj。 ⑤10行,用document接口的write方法显示文档树的第一个结点名 (即根元素名称)。
9.2 一个DOM示例 ⑥13-27行,组织双重循环,遍历文档树的所有孩子结点,并显示。 在此段代码中使用的childNodes、 length、item、nodeName、hasChildNodes等,就是XML DOM核心接口的属性和方法,它们的含义将在本章的后续内容中讨论。
9.3 DOM基础知识9.3.1 DOM的结构模型 DOM提供非常专门的接口把文档表示成结点对象的分级结构。在文档结构中,某些类型的接口可以具有不同的孩子结点,另外一些则提供没有孩子结点的叶子结点,参考图9.3。文档结点是DOM树的根结点,根下是根元素结点,根元素下可以包含子元素结点,并携带属性结点。子元素还可以包含子元素结点、文本结点,……等等,关于元素结点的定义是递归的。属性结点可以是实体、实体引用、表示法、CDATA节等结点。
Document Element Attribute Attribute Entity Notation Element Element Element Text Element …… 图9.3 DOM树结构 9.3.1 DOM的结构模型
9.3.1 DOM的结构模型 在DOM 3的核心中有些什么样的结点类型以及孩子结点的类型,由下面的接口给予简单说明: ◆Document——Element、ProcessingInstruction、Comment、 DocumentType。 ◆DocumentFragment——Element、ProcessingInstruction、Comment、Text、CDATASection、EntityReference。 ◆ DocumentType——无孩子。 ◆ EntityReference——Element、ProcessingInstruction、Comment、Text、CDATASection、EntityReference。 ◆Element——Element、Text、Comment、ProcessingInstruction、CDATASection、 EntityReference。 ◆Attr——Text、EntityReference。 ◆ProcessingInstruction——无孩子。
9.3.1 DOM的结构模型 ◆Comment——无孩子。 ◆Text——无孩子。 ◆CDATASection——无孩子。 ◆Entity——Element、ProcessingInstruction、Comment、Text、CDATASection、 EntityReference。 ◆Notation——无孩子。 DOM还定义了NodeList接口来处理结点的有序列表,譬如一个结点的所有孩子序列。另外,通过引用结点的名称属性(如一个元素的属性),提供了Element.getElementsByTagNameNS方法返回的element和NamedNodeMap接口来处理结点的无序集合。NodeList和 NamedNodeMap对象在DO DOM中富有活力,对于文文件结构基础
9.3.1 DOM的结构模型 的任何修改将反映在所有的相关的NodeList和NamedNodeMap对象中。 例如,如果一个DOM用户得到一个包含孩子元素的NodeList对象,那么对该元素的增加、修改或删除孩子等操作会自动反映在 NodeList对象中,而无须用户方进一步操作。类似的,对一个树中结点的修改会反映在所有引用该结点的NodeList和NamedNodeMap对象中。 另外,结点Text、Comment和CDATASection都是继承CharacterData接口的。 DOM的接口分为基本接口和扩展接口。本节讨论基本接口。
9.3.2 核心模块基础知识 基本接口是DOM的所有处理程序完全实现的那些接口,包括HTML DOM处理程序。 DOM应用可以用DOMImplementation.hasFeature(feature, version)方法,分别携带参数"Core"和"3.0"来决定该模块是否由基本接口支持。任何与DOM 3一致的处理程序。或者模块必须与此核心模块一致。DOM 3 核心模块向后兼容DOM Level 2的核心模块。 1、基本接口 在DOM 3核心模块中,有23个接口,它们简单表示在表9.1中。 表9.1的接口都有具体的定义,限于篇幅,在本书里只讨
9.3.2 核心模块基础知识 论几个常用的接口定义,其余的接口,读者可以参考http://www.w3.org/TR/2004/REC-DOM-Level-3-core。另外,为了说明问题,只在Document接口中完整使用了DOM规范的定义形式,提供给读者作为一种参考。其余的接口,将简化描述。 2、结点类型 在DOM中定义了12类型结点,它们代表不同的结点类型,以及不同的概念和操作。表9.2列出了结点类型、参数和常量。 这些类型口完全包含xml 1.0中定义的结点类型,这是为了方便处理XML结点, XML DOM的设计目的由此可见一斑。
9.3.2 核心模块基础知识 表9.1 DOM 3核心接口列表
9.3.2 核心模块基础知识 3.基础类型 为了保证互操作性,DOM定义了下列基础类型,用于不同的DOM模块。 (1)DOM串类型 DOM串类型用来把Unicode字符保存成用UTF-16编码的以2个字节为单位的序列。这些字符由XML1.0的附录B定义。 选择UTF-16编码是因为它在业界广泛使用。对于HTML和XML,文档字符集以UCS(UCS [ISO/IEC 10646])为基础。在源文档中引用的单个数字字符可能对应于DOM字符串的2个16位二进制数。
9.3.2 核心模块基础知识 表9.2 DOM 3的结点类型定义
9.3.2 核心模块基础知识 (2)DOM时戳类型 DOM时戳类型用于存储绝对时间和相对时间。对于Java,DOMTimeStamp绑定给长整型类型。 (3)DOM用户数据类型 DOM用户数据类型用于存储应用程序的数据。对于Java,用户数据类型绑定给对象类型。 (4)DOM对象类型 DOM对象类型用于表示一个对象。 对于Java,DOM对象绑定给对象类型。
9.4 DOM常用接口9.4.1 Document接口 Document接口表示整个HTML或XML文档。概念上,它是文档树的根并提供对文档数据的初始访问入口。 因为元素、文本结点、注释、处理指令等不可能存在于文档的上下文之外,Document接口还包含创建这些对象的整体方法。该接口的接口定义语言描述形式如下:
attribute DOMString xmlVersion; // raises(DOMException) on setting attribute boolean strictErrorChecking; attribute DOMString documentURI; Node adoptNode(in Node source) raises(DOMException); readonly attribute DOMConfiguration domConfig; void normalizeDocument(); Node renameNode(in Node n, in DOMString namespaceURI, in DOMString qualifiedName) raises(DOMException); };
9.4.1 Document接口 1、属性 ◆doctype DocumentType类型,只读。 定义与文档相关的文档类型声明,对于没有文档类型声明的XML文档,返回null。对于HTML文档,无论HTML的文档类型声明是否存在,可以返回DocumentType对象。 ◆documentElementElement类型,只读。 这是一个常用方便的的属性,用于直接访问文档的文档元素子结点。 ◆documentURI DOMString类型 文档位置,如果未定义或者文档用DOMImplementation.createDocument来建立,该值是null。设置该属性时,不需要进行词汇检查。
9.4.1 Document接口 ◆domConfig DOMConfiguration类型,只读。 使用Document.normalizeDocument()时用来配置。 ◆implementation DOMImplementation类型,只读。 是处理该文档的DOMImplementation对象,一个DOM的应用程序可以从多个处理中使用这个对象。 ◆inputEncoding DOMString类型,只读。 定义在解析文档时使用的编码。该属性未知时值为null,如文档在内存中创建时的情形。 ◆strictErrorChecking boolean类型。 定义是否强制进行错误检查的属性。
9.4.1 Document接口 ◆xmlEncodingDOMString类型,只读。 作为XML声明的一部分定义的属性,表示该XML文档的编码。 ◆xmlStandalone boolean类型。 作为XML声明的一部分定义的属性,表示该XML文档的独立性。未定义时,该值为false。 ◆xmlVersionDOMString类型。 作为XML声明的一部分定义的属性,表示该XML文档的版本。如果没有声明和如果该文档支持“XML” 特征,该值是“1.0”。如果该文档不支持“XML”特征,该值永远是null。
9.4.1 Document接口 2、方法 ◆adoptNode (1)功能:试图从其它文档接受一个结点到该文档。如果支持该方法,它改变源结点及其孩子和与该结点相关的属性的文档所有者。如果源结点有父元素,首先从这个父元素的孩子列表中删除该结点。这实际上允许把一棵子树从一个文档移动到另一个文档。 (2)操作的结点类型:该方法可以操作的结点类型有: ATTRIBUTE_NODE、DOCUMENT_FRAGMENT_NODE、ELEMENT_NODE、 ENTITY_REFERENCE_NODE、PROCESSING_INSTRUCTION_NODE、TEXT_NODE、 CDATA_SECTION_NODE、COMMENT_NODE。
9.4.1 Document接口 该方法不允许使用的结点类型是:DOCUMENT_NODE、DOCUMENT_TYPE_NODE、ENTITY_NODE、NOTATION_NODE。 (3)参数: 结点型的参数 source表示移入该文档的结点。 (4)返回值:返回值是接受的结点类型。如果操作失败,则返回null。 (5)出错:如果源结点类型是DOCUMENT, DOCUMENT_TYPE则引起NOT_ SUPPORTED_ERR错误。如果源结点为只读,引起NO_MODIFICATION_ALLOWED_ERR错误。
9.4.1 Document接口 ◆createAttribute (1)功能:建立给定名称的属性。属性的实例setAttributeNode可以用方法来设置。为了建立携带合格名称和名称空间URI的属性,使用createAttributeNS方法。 (2)参数:参数name 表示属性的名称。 (3)返回值:属性值为空字符串。 (4)出错:如果给定的具体名称不是在Document.xmlVersion属性中规定的符合XML版本的XML名称时,引起INVALID_CHARACTER_ERR。 例如,为例9.1的文档增加一个属性结点id,作为file的访问句柄。 var newNode=xmlDom. createAttribute ("id");
9.4.1 Document接口 XML名称时,引起INVALID_CHARACTER_ERR。 例如,为例9.1的文档增加一个属性结点id,作为file的访问句柄。 var newNode=xmlDom. createAttribute ("id"); ◆ createAttributeNS (1)功能:建立给定的合格名称和名称空间URI的一个属性。如果不需要名称空间,应用程序必须具有null作为namespaceURI参数值。 (2)参数:参数namespaceURI表示要建立属性的名称空间URI。参数qulifiedName表示要用实例说明的属性的合格名称。
9.4.1 Document接口 (3)返回值:创建的属性有6个属性:Node.nodeName、Node.namespaceURI、Node.prefix、Node.localName、Attr.name和Node.nodeValue。其中Node.nodeName的值为合格名称;Node.namespaceURI的值是名称空间URI; Node.prefix是前缀,来自合格名称; Node.localName是本地名称;Attr.name是合格名称;Node.nodeValue的值为空串。 (4)出错:如果给定的具体名称不是在Document.xmlVersion属性中规定的符合XML版本的XML名称时,引起INVALID_CHARACTER_ERR。如果合格名称是残缺不全的引起NAMESPACE_ERR。如果当前不支持"XML" 特征,永远出现NOT_SUPPORTED_ERR错误。
9.4.1 Document接口 ◆createCDATASection (1)功能:建立一个CDATASection结点,它的值是确定的字符串。 (2)参数:参数data表示要建立的CDATASection的内容。 (3)返回值:新的CDATASection对象。 (4)出错:如果该文档是一个HTML文档,引起NOT_SUPPORTED_ERR错误。如果合格名称是残缺不全的引起NAMESPACE_ERR。如果当前不支持"XML" 特征,永远出现NOT_SUPPORTED_ERR错误。
9.4.1 Document接口 ◆ createComment (1)功能:建立一个Comment结点,它的值是确定的字符串。 (2)参数:参数data表示要建立的Comment结点的内容。 (3)返回值:新的Comment对象。 (4)出错:无。 ◆createDocumentFragment (1)功能:建立一个空的DocumentFragment对象。 (2)参数:无。 (3)返回值:新的DocumentFragment对象。 (4)出错:无。
9.4.1 Document接口 ◆createElement (1)功能:建立一个确定类型的元素。注意,返回的实例处理Element接口,所以属性可以直接定义给返回的对象。另外,如有已知属性携带默认值,表示 它们的属性结点自动被建立并附加到该元素上。要建立携带合格名称和名称空间URI的元素,请使用createElementNS方法。 (2)参数:参数tagName表示要有实例说明的元素类型名称。 (3)返回值:新的Element对象,携带设置为tagName的结点名称属性,并且,本地名称、前缀和名称空间URI设置为null。
9.4.1 Document接口 (4)出错:如果给定的具体名称不是在Document.xmlVersion属性中规定的符合XML版本的XML名称时,引起INVALID_CHARACTER_ERR。 如创建一个名为file的元素结点: var newNode=xmlDom.createElement("file"); ◆createElementNS (1)功能:建立一个给定合格名称和名称空间URI的元素。如果不需要名称空间,应用程序必须具有null作为namespaceURI参数值。 (2)参数:参数namespaceURI表示要建立元素的名称空间URI。参数qulifiedName表示要用实例说明的元素类型的合格名称。
9.4.1 Document接口 (3)返回值:新的Element对象,携带属性:Node.nodeName、Node.namespaceURI、Node.prefix、Node.localName、Element.tagName,它们的返回值分别是:合格名称、名称空间URI、前缀、本地名称和合格名称。 (4)出错:出错的情况与createAttributeNS一致。 ◆createEntityReference (1)功能:建立一个EntityReference对象。另外,如果已知引用的实体,EntityReference结点的子结点列表与其相应的Entity结点列表一样。 (2)参数:参数name表示要引用的实体名称。 (3)返回值:新的EntityReference对象。
9.4.1 Document接口 (4)出错:如果给定的具体名称不是在Document.xmlVersion属性中规定的符合XML版本的XML名称时,引起INVALID_CHARACTER_ERR。如果文档是HTML文档,引起NOT_SUPPORTED_ERR错误。 ◆createTextNode (1)功能:建立一个给定具体串值的text结点。 (2)参数:参数data表示结点的数据。 (3)返回值:新的text对象。 (4)出错:无。 如创建一个结点值为“张明”文本结点: var newText=xmlDom.createTextNode("张明");
9.4.1 Document接口 ◆ getElementById (1)功能:返回具有ID属性和给定值的Element。如果没有此类元素存在,返回null。如果多个元素具有ID属性和该给定值,返回哪一个元素没有定义。期望DOM处理程序使用Atrr.isId来检测属性是否为一个ID类型。 (2)参数:参数elementId表示一个元素的唯一的id值。 (3)返回值:与方法匹配的元素,如果没有元素则为null。 (4)出错:无。 ◆getElementsByTagName (1)功能:返回具有给定tag名称的并包含在文档内的所有元素的结点列表,列表顺序与文档顺序一致。
9.4.1 Document接口 (2)参数:参数tagname表示要进行匹配的标签名称。特殊值“*”匹配所有的标签。对于XML,tagname是区分大小写的。否则将依据所使用的其他标记语言字母匹配特性。 (3)返回值:包含所有匹配元素的新的结点列表对象 (4)出错:无。 例如,通过getElementsByTagName方法获得指定名称student的元素的第1个子项目。 xmlnode.getElementsByTagName("student").item(1); ◆ getElementsByTagNameNS (1)功能:返回具有给定本地名称和名称空间URI的所有元素的结点列表,列表顺序与文档顺序一致。
9.4.1 Document接口 (2)参数:参数tagname表示要进行匹配的标签名称。特殊值“*”匹配所有的名称空间。LocalName表示要进行匹配的元素的本地名称。 (3)返回值:包含所有匹配元素的新的结点列表对象。 (4)出错:无。 ◆importNode (1)功能:从其它文档输入一个结点到该文档,不改变或删除源文档的源结点。该方法建立源结点的一个新的拷贝。返回的结点没有父元素。对于所有结点,输入一个结点就建立了属于输入文档拥有的结点对象,该结点的属性值与源结点的结点名和结点类型相同,还要加上与该属性相关的
9.4.1 Document接口 名称空间(前缀,本地名称和名称空间URI)。 (2)操作的结点类型:输入操作只能输入一部分结点,它们是:ATTRIBUTE_NODE、DOCUMENT_FRAGMENT_NODE、ELEMENT_NODE、ENTITY_NODE、ENTITY_ REFERENCE_NODE、NOTATION_NODE、PROCESSING_INSTRUCTION_NODE、TEXT_NODE、CDATA_SECTION_NODE、COMMENT_NODE。 (3)参数:参数importedNode表示要输入的结点。参数deep表示是否输入结点的子树,是布尔型变量,值为true时递归地输入子树,否则只输入结点自己。此参数对没有孩子的结点不起作用。 (4)返回值:属于本文档的输入结点。
9.4.1 Document接口 (5)出错:如果输入结点类型不被支持,引起NOT_SUPPORTED_ERR。如果输入结点的名字不是一个合格的XML名称,引起INVALID_CHARACTER_ERR错误。 ◆normalizeDocument (1)功能:如果一个文档正在被保存和调用,这个方法把该文档置为普通形式。 (2)参数:无。 (3)返回值:无。 (4)出错:无。 ◆renameNode (1)功能:修改现存的ELEMENT_NODE类型和ATTRIBUTE_NODE类型结点的名称。可能情况下,此方法简单修改给定结点的名
9.4.1 Document接口 称。否则建立一个确定名称的新结点并替换此现存结点。 (2)参数:参数n表示要改名的结点。参数namespaceURI表示新的名称空间URI。参数qualifiedName表示新的合格名称。 (3)返回值:被改名的结点。 (4)出错:如果确定结点不是ELEMENT_NODE和ATTRIBUTE_NODE,如果操作不支持文档元素的改名,引起NOT_SUPPORTED_ERR错误。如果新的合格名称不是一个XML名称时,引起INVALID_CHARACTER_ERR错误。如果参数qualifiedName是一个不完整的合格名称,引起NAMESPACE_ERR错误。如果确定的结点是从与本文档不同的文档创建的,引起WRONG_DOCUMENT_ERR错误。
9.4.2 Node接口 Node接口是整个文档对象模型的基本数据类型。它表示文档树的单个结点。是DOM应用中最常用的接口之一。下面的所以讨论采用简单形式。 1、属性 node接口的属性有:
9.4.2 Node接口 2、常用方法 ◆appendChild 在该结点的孩子列表的末尾增加一个新子结点。如果新子结点已存在,则事先删除它,然后添加。例如在xmlDOM的文档树上增加一个新结点的操作: var xmlroot=xmlDom.documentElement.appendChild(newNode); ◆ cloneNode 返回此结点的复制品。对于元素结点,将复制所有的属性和属性值。对于属性结点,则返回它的孩子。 ◆hasChildNodes 返回该结点是否有子结点,是布尔型,当取true时,说
9.4.2 Node接口 明该结点有孩子。否则无孩子。例如,判断结点是否有孩子结点,然后进行操作。 if(xmlObj.item(i).hasChildNodes){……} ◆ insertBefore 在参考子结点前插入一个新子结点。例如,在xmlDOM对象上创建一个新结点,然后把该结点插入到另外一个结点xmlnode的最后一个孩子前。 Var newNode=xmlDom.createElement("file"); xmlnode.insertBefore(newNode,xmlnode.lastChild);
9.4.2 Node接口 ◆ removeChild 从孩子列表中删除指定的子结点,并返回它。例如,删除通过getElementsByTag- Name(“file”)方法获得指定结 点。 ◆replaceChild 在孩子结点列表中,用新结点替换一个旧结点,并返回旧结点。
9.4.3 Element接口 该接口表示HTML或XML文档中的元素。元素可以携带相关的属性,因为元素接口继承结点接口,通用的node接口的attribute属性可以用来获取一个元素的所有属性的集合。 1、属性 ◆schemaTypeInfo与该元素相关的信息类。 ◆TagName元素的名称,如果Node.localName与null不同,此属性是一个合格的名称。 2、常用方法 ◆getAttribute通过名称参数获得属性值。 ◆getAttributeNode通过名称参数获得属性结点。 ◆getElementsByTagName以文档顺序返回携带给定标