文档对象模型(DOM)是XML文件的逻辑视图。
在DOM中,XML文档包含在XmlDocument类中, 通过XmlNode可以访问和管理该文档中的每个节点。
通过使用诸如XmlWriter类、TextWriter 类、Stream类等,从XmlDocument中提取XML文档。
与流访问不同,使用DOM可灵活访问前后各节点,删除与更新更方便。
DOM和XML序列化最大的区别:使用序列化技术时,节点类型(如属性或元素)和节点名是在编译时指定的,因此不能自由修改序列化进程生成的XML。
一.XML 文档对象模型 (DOM)
XML 文档对象模型 (DOM) 类是 XML 文档的内存中表示形式。
DOM 使您能够以编程方式读取、处理和修改 XML 文档。XmlReader 类也读取 XML,但它提供非缓存的只进、只读访问。
这意味着使用 XmlReader 无法编辑属性值或元素内容,也无法插入和移除节点。编辑是 DOM 的主要功能。
XML 数据在内存中表示是常见的结构化方法,尽管实际的 XML 数据在文件中时或从另一个对象传入时以线性方式存储。以下是 XML 数据。
下图显示将此 XML 数据读入 DOM 结构中时如何构造内存(XML 文档结构)。
<?xml version="1.0"?> <books> <book> <author>Carson</author> <price format="dollar">31.95</price> <pubdate>05/01/2001</pubdate> </book> <pubinfo> <publisher>MSPress</publisher> <state>WA</state> </pubinfo> </books>
图中的每个圆圈表示一个节点(称为 XmlNode 对象)。XmlNode 对象是 DOM 树中的基本对象。
XmlDocument 类(扩展 XmlNode)支持用于对整个文档执行操作(例如,将文档加载到内存中或将 XML 保存到文件中)的方法。
此外,XmlDocument 提供了查看和处理整个 XML 文档中的节点的方法。XmlNode 和 XmlDocument 都具有性能和可用性增强,并通过方法和属性执行下列操作:
1、访问和修改 DOM 特定的节点,如元素节点、实体引用节点等。2、除检索节点包含的信息(如元素节点中的文本)外,还检索整个节点。
DOM 的一个特性是处理属性的方式。
属性是不属于父子关系和同辈关系的节点。属性被视为元素节点的属性,由名称和值对组成。
例如,如果存在由与元素 price 关联的 format="dollar" 组成的 XML 数据,则单词 format 是名称,format 属性的值是 dollar。为检索 price 节点的 format="dollar" 属性,可以在游标位于 price 元素节点时调用 GetAttribute 方法。
将 XML 读入内存时会创建节点。然而,并非所有节点都是同一类型。二、System.Xml中用于DOM的类
(一)XmlDocument类
完整的XML文档。
可用Load或LoadXml方法加载文档:
1、使用Load方法可以从文件(文件名被指定为String^型)、TextReader或XmlReader中加载 XML文档。
2、使用LoadXml方法从包含XML文档的字符串中加载文档。
Save方法用于存储XML文档。
XmlDocument有多种对XML文档进行的复杂操作。例如:
CreateAttribute、CreateCDataSection、CreateComment、CreateDocumentFragment、CreateDocumentType:、CreateElement、CreateEntityReference、CreateNavigator、CreateNode、CreateProcessinglnstruction、CreateSignificantWhitespace、 CreateTextNode、CreateWhitespace和CreateXmlDeclaration。文档中的兀素可以被获取。类的其他方法支持获取、导入、复制、加载和写入节点。
(二)XmlNode类
对应于DOM目录树中的节点,是其他节点类型的类的基类。它提供了一组创建、删除和替换节点的方法和属性。同样,节点内容可以通过各种方式遍历:FirstChild、 LastChild、NextSibling、ParentNode 和 PrevIoUsSibling。
(三)XmElement类
对应于DOM目录树中的元素。该类所公开的功能包含许多用于操作元素特性的方法。
(四)XmlAttribute类
对应于DOM目录树中元素(XmlElement)的一个特性。特性包含数据和下一层级的数据列表,因此它比XmlNode或XmlElement更简单。XmlAttribute可以获取它所在的文档(属性OwnerDocument)、所在的元素(属性OwnerElement)、父节点(属性ParentNode)、名称(属性Name)。XmlAttribute的值可以通过一个读写属性Value来获得。
三、使用DOM读取XML元素
XML文本允许在Visual Basic源代码中直接插入一块 XML,不必使用引号。这些XML文本可以写在多个行上,并可以在任何加载XML文件:(而且会发现在vs输入后,会自动对齐排版)
Dim rawData = <multiFilmOrders> <FilmOrder> <name>Grease</name> <filmld>101</filmld> <quantity>10</quantity></FilmOrder> <FilmOrder> <name>Lawrence of Arabia</name> <filmld>102</filmld> <quantity>10</quantity> </FilmOrder> </multiFilmOrders><FilmOrder>元素的每一个节点,均可用GetElementsByTagName()方法从XmlDocument中获得。
该方法以XmlNodeList类型集合的形式返冋-个 XmlNode对象的列表。
通过使用For Each语句构造这个列表,可以对XmlNodeList (movieOrderNodes) 中的XmlNode元素(movieOrderNode)进行遍历:
Imports System.Xml Public Class Form1 Private Sub btnDom_Click(sender As Object,e As EventArgs) Handles btnDom.Click 'XML文档的字符串 Dim rawData = <multiFilmOrders> <FilmOrder> <name>Grease</name> <filmld>101</filmld> <quantity>10</quantity></FilmOrder> <FilmOrder> <name>Lawrence of Arabia</name> <filmld>102</filmld> <quantity>10</quantity> </FilmOrder> </multiFilmOrders> Dim xmlDoc As New XmlDocument Dim xmlNodes As XmlNodeList Dim xmlNode As XmlNode Dim strNodeXml As String = "" Dim strNodeText As String = "" 'load()是加载xml文档,LoadXml()是加载xml字符串 xmlDoc.LoadXml(rawData.ToString) xmlNodes = xmlDoc.GetElementsByTagName("FilmOrder") For Each xmlNode In xmlNodes strNodeXml &= xmlNode.Name & ":" & xmlNode.InnerXml & vbCrLf strNodeText &= xmlNode.Name & ":" & xmlNode.InnerText & vbCrLf Next 'XmlNode.InnerXml 属性:获取或设置仅代表该节点的子节点的标记。 'XmlNode.InnerText 属性:获取或设置节点及其所有子节点的串联值。 TextBox1.Text = strNodeXml & vbCrLf & strNodeText End Sub End Class
四、使用DOM写入XML
可以使用DOM创建或编辑XML文档。
创建一个新的XML项需要两步。首先,使用包含文档创建新元素、特性或注释(或其他节点类型);然后,将它添加到文档中适当的位置。
XmlDocument类有多种方法创建新节点,例:CreateNode、CreateElement、CreateAttribute、 CreateComment等。
创建了节点后,就可以使用XmlNode(或其子类)的一些方法:AppendChild、CreateNavigator、InsertAfter、InsertBefore、PrependChild、RemoveAll、RemoveChild、ReplaceChild、SelectSingleNode。
Imports System.Xml Public Class Form1 Private Sub btnRead_Click(sender As Object,e As EventArgs) Handles btnRead.Click Dim strXml As String Dim strFileName As String = "3.xml" strXml = CreateXmlFile(strFileName) TextBox1.Text = strXml End Sub Private Function CreateXmlFile(ByVal strFile As String) As String Dim xmlDoc As New XmlDocument Dim xmlEle As XmlElement Dim root As XmlElement = xmlDoc.CreateElement("FilmOrderList") '创建节点元素 xmlDoc.AppendChild(root) '将该节点添加进xml文档 For i As Integer = 1 To 4 xmlEle = CreateFileorder(xmlDoc,i) root.AppendChild(xmlEle) Next xmlDoc.Save(strFile) '保存到文件 Return xmlDoc.OuterXml '提取xml文档中所有字符 End Function Private Function CreateFileorder(ByVal doc As XmlDocument,ByVal n As Integer) As XmlElement Dim id As XmlAttribute Dim film As XmlElement,title As XmlElement,quantity As XmlElement film = doc.CreateElement("FilmOrder") '创建FileOrder结点 id = doc.CreateAttribute("ID") '创建ID属性结点 id.Value = 100 + n film.Attributes.Append(id) '将ID属性结点添加到FileOrder结点 title = doc.CreateElement("Title") '创建Title结点 title.InnerText = "some title here" film.AppendChild(title) '将Title结点作为FileOrder的子结点 quantity = doc.CreateElement("Quantity") quantity.InnerText = "here is quantity" film.AppendChild(quantity) Return film End Function Private Sub btnDom_Click(sender As Object,e As EventArgs) Handles btnDom.Click 'XML文档的字符串 Dim rawData = <multiFilmOrders> <FilmOrder> <name>Grease</name> <filmld>101</filmld> <quantity>10</quantity></FilmOrder> <FilmOrder> <name>Lawrence of Arabia</name> <filmld>102</filmld> <quantity>10</quantity> </FilmOrder> </multiFilmOrders> Dim xmlDoc As New XmlDocument Dim xmlNodes As XmlNodeList Dim xmlNode As XmlNode Dim strNodeXml As String = "" Dim strNodeText As String = "" 'load是加载xml文档,LoadXml是加载xml字符串 xmlDoc.LoadXml(rawData.ToString) xmlNodes = xmlDoc.GetElementsByTagName("FilmOrder") For Each xmlNode In xmlNodes strNodeXml &= xmlNode.Name & ":" & xmlNode.InnerXml & vbCrLf strNodeText &= xmlNode.Name & ":" & xmlNode.InnerText & vbCrLf Next 'XmlNode.InnerXml 属性:获取或设置仅代表该节点的子节点的标记。 'XmlNode.InnerText 属性:获取或设置节点及其所有子节点的串联值。 TextBox1.Text = strNodeXml & vbCrLf & strNodeText End Sub End Class
上例中显示时会发现xml并不是“标准”的xml文档,故另须添加声明结点、注释结点,然后再插入即可:
Dim xmlDoc As New XmlDocument Dim xmlEle As XmlElement Dim xmlDecl As XmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0",Nothing,Nothing) Dim xmlComm As XmlComment = xmlDoc.CreateComment("以下是程序设置,请勿修改") Dim root As XmlElement = xmlDoc.CreateElement("FilmOrderList") '创建节点元素 xmlDoc.CreateXmlDeclaration("1.0",Nothing) xmlDoc.AppendChild(root) '将该节点添加进xml文档 xmlDoc.InsertBefore(xmlComm,root) xmlDoc.InsertBefore(xmlDecl,xmlComm)