【C# XML】DOM文档对象模型
参考: 深入理解DOM节点类型第一篇——12种DOM节点类型概述
w3c DOM文档对象模型
概述:w3c DOM文档对象模型包含3个DOM级别,11个信息项目=>12个节点类型,一种节点导航,2种查询语言 xpath、linqDOM文档定义
DOM全称为文档对象模型(Document Object Model)。根据W3C,文档对象模型(DOM)是“有效HTML和格式良好的XML文档的应用程序编程接口。它定义了文档的逻辑结构以及文档的访问和操作方式”。
是用来呈现以及与任意 HTML 或 XML文档交互的API。DOM 是载入到浏览器中的文档模型,以节点树的形式来表现文档,每个节点代表文档的构成部分(例如:页面元素、字符串或注释等等)。DOM 并不是天生就被规范好了的,它是浏览器开始实现JavaScript时才出现的。这个传统的 DOM 有时会被称为 DOM 0。现在, WHATWG维护DOM现存标准。浏览器会根据DOM模型,将HTML文档解析成一系列的节点,再由这些节点组成一个树状结构。DOM的最小组成单位叫做节点(node),文档的树形结构(DOM树)由12种类型的节点组成。本文将主要说明DOM节点类型
3种DOM级别
DOM1
DOM1级由两个模块组成:DOM核心(DOM CORE)和DOM HTML。其中,DOM核心规定的是如何映射基于XML的文档结构,以便简化对文档中任意部分的访问和操作。DOM HTML模块则在DOM核心的基础上加以扩展,添加了针对HTML的对象和方法。
总结:DOM1主要定义的是HTML和XML文档的底层结构。
DOM2
DOM2级在原来的DOM基础上又扩充了鼠标和用户界面事件、范围、遍历(迭代DOM文档方法)等细分模块,通过对象接口增加了对CSS的支持。
DOM2核心(DOM Core):在1级核心基础上建设,为节点添加了更多方法和属性。
DOM2HTML(DOM HTML):在1级html基础上,添加了更多属性、方法和新接口。
DOM2新引入模块:
DOM2视图(DOM Views):为文档定义了基础样式信息的不同信息。
DOM2事件(DOM Events):说明了如何使用事件与DOM文档交互,比如addEventListener()和removeListener()。DOM事件流发生在此阶段。
DOM2样式(DOM Style):定义了如何以编程方式来访问和改变CSS样式信息。
DOM2遍历和范围(DOM Traversal and Range):引入遍历DOM文档和选择其特定部分的接口。
DOM3
DOM Level 3 建立于 DOM Core Level 2 之上。
DOM3引入了以统一方式加载和保存文档的方法,即在DOM加载和保存(DOM Load and Save)模块中进行定义。
新增了验证文档方法,即在DOM验证(DOM Validation)模块中定义。
同时DOM3级也对DOM核心进行了扩展,开始支持XML1.0规范。
注:
1、DOM2和DOM3级的目的在于扩展DOM API。DOM2核心并没有引入新类型,只在DOM1的基础上通过增新方法和新属性来增强已有类型。DOM3核心既增强已有类型,也引入了一些新类型。
2、DOM0级标准是不存在的,所谓DOM0级只是DOM历史坐标中一个参照点而已。具体来说,DOM0级指的是IE4和Netscape Navigator4.0最初支持的DHTML。
C# XmlDocument实现了DOM1级 core、DOM2级 core、DOM3级
节点属性
一般地,节点至少拥有nodeType、nodeName和nodeValue这三个基本属性。节点类型不同,这三个属性的值也不相同
DOM文档总共11种不同类型的信息项:
- 文档讯息项 (总是存在)Document Information Item
- 元素讯息项(Element Information Item)
- 属性讯息项(Attribute Information Item)
- PI讯息项(Processing Instruction Information Item)
- 未扩展实体引用讯息项(Unexpanded Entity Reference Information Item)
- 字元讯息项(Character Information Item)
- 注释讯息项(Comment Information Item)
- 文档型别宣告讯息项(The Document Type Declaration Information Item)
- 非解析实体讯息项(Unparsed Entity Information Item)
- 格式讯息项(Notation Information Item)
- 命名空间讯息项(Namespace Information Item)
注意:数据的基本单位是数据元素,数据项是数据元素的基本组成单元。因此这Dom文档中的11个信息项,是其实就是数据项目。数据项是C#中 属性和字段。
12种节点类型nodeType
nodeType属性返回节点类型的常数值。不同的类型对应不同的常数值,12种类型分别对应1到12的常数值
元素节点 Node.ELEMENT_NODE(1)
属性节点 Node.ATTRIBUTE_NODE(2)
文本节点 Node.TEXT_NODE(3)
CDATA节点 Node.CDATA_SECTION_NODE(4)
实体引用名称节点 Node.ENTRY_REFERENCE_NODE(5)
实体名称节点 Node.ENTITY_NODE(6)
处理指令节点 Node.PROCESSING_INSTRUCTION_NODE(7)
注释节点 Node.COMMENT_NODE(8)
文档节点 Node.DOCUMENT_NODE(9)
文档类型节点 Node.DOCUMENT_TYPE_NODE(10)
文档片段节点 Node.DOCUMENT_FRAGMENT_NODE(11)
DTD声明节点 Node.NOTATION_NODE(12)
DOM定义了一个Node接口,这个接口在javascript中是作为Node类型实现的,而在IE8-浏览器中的所有DOM对象都是以COM对象的形式实现的。所以,IE8-浏览器并不支持Node对象的写法
//在标准浏览器下返回1,而在IE8-浏览器中报错,提示Node未定义
console.log(Node.ELEMENT_NODE);//1
节点类型 - 返回值
对于每种节点类型,nodeName 和 nodeValue 属性的返回值:
节点类型 nodeName 返回 nodeValue 返回
1 Element 元素名 null
2 Attr 属性名称 属性值
3 Text #text 节点的内容
4 CDATASection #cdata-section 节点的内容
5 EntityReference 实体引用名称 null
6 Entity 实体名称 null
7 ProcessingInstruction target 节点的内容
8 Comment #comment 注释文本
9 Document #document null
10 DocumentType 文档类型名称 null
11 DocumentFragment #document 片段 null
12 Notation 符号名称 null
DOM常用节点类型 Node Types
文档、元素、属性以及 HTML 或 XML 文档的其他方面拥有不同的节点类型。
节点类型
存在 12 种不同的节点类型:nodeName,其中可能会有不同节点类型的子节点:
节点类型 描述 子节点
1 Element 代表元素 Element, Text, Comment, ProcessingInstruction, CDATASection, EntityReference
2 Attr 代表属性 Text, EntityReference
3 Text 代表元素或属性中的文本内容。 None
4 CDATASection 代表文档中的 CDATA 部分(不会由解析器解析的文本)。 None
5 EntityReference 代表实体引用。 Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference
6 Entity 代表实体。 Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference
7 ProcessingInstruction 代表处理指令。 None
8 Comment 代表注释。 None
9 Document 代表整个文档(DOM 树的根节点)。 Element, ProcessingInstruction, Comment, DocumentType
10 DocumentType 向为文档定义的实体提供接口 None
11 DocumentFragment 代表轻量级的 Document 对象,能够容纳文档的某个部分 Element, ProcessingInstruction, Comment, Text, CDATASection, EntityReference
12 Notation 代表 DTD 中声明的符号。 None
元素节点
元素节点element对应网页的HTML标签元素。元素节点的节点类型nodeType值是1,节点名称nodeName值是大写的标签名,nodeValue值是null
以body元素为例
// 1 'BODY' null
console.log(document.body.nodeType,document.body.nodeName,document.body.nodeValue)
console.log(Node.ELEMENT_NODE === 1);//true
特性节点
元素特性节点attribute对应网页中HTML标签的属性,它只存在于元素的attributes属性中,并不是DOM文档树的一部分。特性节点的节点类型nodeType值是2,节点名称nodeName值是属性名,nodeValue值是属性值
现在,div元素有id="test"的属性
<div id="test"></div>
<script>
var attr = test.attributes.id;
//2 'id' 'test'
console.log(attr.nodeType,attr.nodeName,attr.nodeValue)
console.log(Node.ATTRIBUTE_NODE === 2);//true
</script>
文本节点
文本节点text代表网页中的HTML标签内容。文本节点的节点类型nodeType值是3,节点名称nodeName值是'#text',nodeValue值是标签内容值
现在,div元素内容为'测试'
<div id="test">测试</div>
<script>
var txt = test.firstChild;
//3 '#text' '测试'
console.log(txt.nodeType,txt.nodeName,txt.nodeValue)
console.log(Node.TEXT_NODE === 3);//true
</script>
CDATA节点
CDATASection类型只针对基于XML的文档,只出现在XML文档中,表示的是CDATA区域,格式一般为
<![CDATA[
]]>
该类型节点的节点类型nodeType的值为4,节点名称nodeName的值为'#cdata-section',nodevalue的值是CDATA区域中的内容
实体引用名称节点
实体是一个声明,指定了在XML中取代内容或标记而使用的名称。 实体包含两个部分, 首先,必须使用实体声明将名称绑定到替换内容。 实体声明是使用 <!ENTITY name "value"> 语法在文档类型定义(DTD)或XML架构中创建的。其次,在实体声明中定义的名称随后将在 XML 中使用。 在XML中使用时,该名称称为实体引用。
实体引用名称节点entry_reference的节点类型nodeType的值为5,节点名称nodeName的值为实体引用的名称,nodeValue的值为null
//实体名称
<!ENTITY publisher "Microsoft Press">
//实体名称引用
<pubinfo>Published by &publisher;</pubinfo>
实体名称节点
上面已经详细解释过,就不再赘述
该节点的节点类型nodeType的值为6,节点名称nodeName的值为实体名称,nodeValue的值为null
处理指令节点
处理指令节点ProcessingInstruction的节点类型nodeType的值为7,节点名称nodeName的值为target,nodeValue的值为entire content excluding the target
注释节点
注释节点comment表示网页中的HTML注释。注释节点的节点类型nodeType的值为8,节点名称nodeName的值为'#comment',nodeValue的值为注释的内容
现在,在id为myDiv的div元素中存在一个<!-- 我是注释内容 -->
<div id="myDiv"><!-- 我是注释内容 --></div>
<script>
var com = myDiv.firstChild;
//8 '#comment' '我是注释内容'
console.log(com.nodeType,com.nodeName,com.nodeValue)
console.log(Node.COMMENT_NODE === 8);//true
</script>
文档节点
文档节点document表示HTML文档,也称为根节点,指向document对象。文档节点的节点类型nodeType的值为9,节点名称nodeName的值为'#document',nodeValue的值为null
<script>
//9 "#document" null
console.log(document.nodeType,document.nodeName,document.nodeValue)
console.log(Node.DOCUMENT_NODE === 9);//true
</script>
文档类型节点
文档类型节点DocumentType包含着与文档的doctype有关的所有信息。文档类型节点的节点类型nodeType的值为10,节点名称nodeName的值为doctype的名称,nodeValue的值为null
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script>
var nodeDocumentType = document.firstChild;
//10 "html" null
console.log(nodeDocumentType.nodeType,nodeDocumentType.nodeName,nodeDocumentType.nodeValue);
console.log(Node.DOCUMENT_TYPE_NODE === 10);
</script>
</body>
</html>
文档片段节点
文档片段节点DocumentFragment在文档中没有对应的标记,是一种轻量级的文档,可以包含和控制节点,但不会像完整的文档那样占用额外的资源。该节点的节点类型nodeType的值为11,节点名称nodeName的值为'#document-fragment',nodeValue的值为null
<script>
var nodeDocumentFragment = document.createDocumentFragment();
//11 "#document-fragment" null
console.log(nodeDocumentFragment.nodeType,nodeDocumentFragment.nodeName,nodeDocumentFragment.nodeValue);
console.log(Node.DOCUMENT_FRAGMENT_NODE === 11);//true
</script>
DTD声明节点
DTD声明节点notation代表DTD中声明的符号。该节点的节点类型nodeType的值为12,节点名称nodeName的值为符号名称,nodeValue的值为null
节点导航
节点导航实现了对文档的遍历,它实现了dom2级中的遍历和范围模块(NodeIterator、axes(轴)也叫TreeWalker)
XPathNavigator在xml.xpath 命名空间,可以通过以下两种方式创建:
XmlDocument创建的XPathNavigator可以编辑
XPathDocument创建的XPathNavigator不可以编辑
DOM 查询语言
Xpath 详细用法查看【C# XML】XPath
Linq