大家好,又见面了,我是你们的朋友全栈君。
一. XmlDocument类: XmlDocument与XmlReader类从.NET 1.0就已经存在了。W3C定义了一个叫做文件对象模型(DOM: Document Object Model)的标准来处理XML文档。支持DOM的类可以自由地定位并修改XML文档。要想使用XmlDocument类,需要添加System.Xml.dll的引用,并且引入System.Xml命名空间。XmlDocument类使用DOM级别1与级别2,在内存中对XML进行表示。这个类可以定位寻找或者修改XML结点。
1.创建XmlDocument对象: 下面这个例子演示了如何使用XmlDocument类。
代码语言:javascript复制 private void createAndSaveXmlDocumentToolStripMenuItem_Click(
object sender, EventArgs e)
{
//Declare and create new XmlDocument
var xmlDoc = new XmlDocument();
XmlElement el;
int childCounter;
int grandChildCounter;
//Create the xml declaration first
xmlDoc.AppendChild(
xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null));
//Create the root node and append into doc
el = xmlDoc.CreateElement("MyRoot");
xmlDoc.AppendChild(el);
//Child Loop
for (childCounter = 1; childCounter <= 4; childCounter )
{
XmlElement childelmt;
XmlAttribute childattr;
//Create child with ID attribute
childelmt = xmlDoc.CreateElement("MyChild");
childattr = xmlDoc.CreateAttribute("ID");
childattr.Value = childCounter.ToString();
childelmt.Attributes.Append(childattr);
//Append element into the root element
el.AppendChild(childelmt);
for (grandChildCounter = 1; grandChildCounter <= 3;
grandChildCounter )
{
//Create grandchildren
childelmt.AppendChild(xmlDoc.CreateElement("MyGrandChild"));
}
}
//Save to file
xmlDoc.Save(getFilePath("XmlDocumentTest.xml"));
txtLog.AppendText("XmlDocumentTest.xml Createdrn");
}
private string getFilePath(string fileName)
{
return Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.Desktop), fileName);
}
最后生成的XML文档如下:
代码语言:javascript复制<?xml version="1.0" encoding="utf-8"?>
<MyRoot>
<MyChild ID="1">
<MyGrandChild />
<MyGrandChild />
<MyGrandChild />
</MyChild>
<MyChild ID="2">
<MyGrandChild />
<MyGrandChild />
<MyGrandChild />
</MyChild>
<MyChild ID="3">
<MyGrandChild />
<MyGrandChild />
<MyGrandChild />
</MyChild>
<MyChild ID="4">
<MyGrandChild />
<MyGrandChild />
<MyGrandChild />
</MyChild>
</MyRoot>
2.使用DOM来解析XmlDocument对象: XmlDocument对象可以使用递归的方法来遍历所有元素。请看下面的例子:
代码语言:javascript复制 private void parsingAndXmlDocumentToolStripMenuItem_Click(object sender, EventArgs e)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(getFilePath("XmlDocumentTest.xml"));
RecurseNodes(xmlDoc.DocumentElement);
}
public void RecurseNodes(XmlNode node)
{
var sb = new StringBuilder();
//start recursive loop with level 0
RecurseNodes(node, 0, sb);
txtLog.Text = sb.ToString();
}
public void RecurseNodes(XmlNode node, int level, StringBuilder sb)
{
sb.AppendFormat("{0,2} Type:{1,-9} Name:{2,-13} Attr:",
level, node.NodeType, node.Name);
foreach (XmlAttribute attr in node.Attributes)
{
sb.AppendFormat("{0}={1} ", attr.Name, attr.Value);
}
sb.AppendLine();
foreach (XmlNode n in node.ChildNodes)
{
RecurseNodes(n, level 1, sb);
}
}
输出的结果如下:
代码语言:javascript复制 0 Type:Element Name:MyRoot Attr
1 Type:Element Name:MyChild AttrID=1
2 Type:Element Name:MyGrandChild Attr
2 Type:Element Name:MyGrandChild Attr
2 Type:Element Name:MyGrandChild Attr
1 Type:Element Name:MyChild AttrID=2
2 Type:Element Name:MyGrandChild Attr
2 Type:Element Name:MyGrandChild Attr
2 Type:Element Name:MyGrandChild Attr
1 Type:Element Name:MyChild AttrID=3
2 Type:Element Name:MyGrandChild Attr
2 Type:Element Name:MyGrandChild Attr
2 Type:Element Name:MyGrandChild Attr
1 Type:Element Name:MyChild AttrID=4
2 Type:Element Name:MyGrandChild Attr
2 Type:Element Name:MyGrandChild Attr
2 Type:Element Name:MyGrandChild Attr
3.搜索XmlDocument对象: SelectSingleNode方法可以用来定位XML元素;它需要将XPath查询传递给该方法。下面的代码演示了如何通过使用XPath查询来调用SelectSingleNode方法查询到ID为3的MyChild元素。
代码语言:javascript复制 private void searchingAnXmlDocumentToolStripMenuItem_Click(
object sender, EventArgs e)
{
var xmlDoc = new XmlDocument();
xmlDoc.Load(getFilePath("XmlDocumentTest.xml"));
var node = xmlDoc.SelectSingleNode("//MyChild[@ID='3']");
RecurseNodes(node);
}
GetElementsByTagName方法返回一个包含所有符合条件的XmlNode列表。
代码语言:javascript复制 private void getElementsByTagNameToolStripMenuItem_Click(
object sender, EventArgs e)
{
var xmlDoc = new XmlDocument();
xmlDoc.Load(getFilePath("XmlDocumentTest.xml"));
var elmts = xmlDoc.GetElementsByTagName("MyGrandChild");
var sb = new StringBuilder();
foreach (XmlNode node in elmts)
{
RecurseNodes(node, 0, sb);
}
txtLog.Text = sb.ToString();
}
SelectNodes方法也需要使用XPath查询来返回一个XmlNode 列表。这个方法要比GetElementsByTagName更灵活,因为GetElementsByTagName局限于标签名(tag name)。
代码语言:javascript复制 private void selectNodesToolStripMenuItem_Click(
object sender, EventArgs e)
{
var xmlDoc = new XmlDocument();
xmlDoc.Load(getFilePath("XmlDocumentTest.xml"));
var elmts = xmlDoc.SelectNodes("//MyGrandChild");
var sb = new StringBuilder();
foreach (XmlNode node in elmts)
{
RecurseNodes(node, 0, sb);
}
txtLog.Text = sb.ToString();
}
二. XmlReader类: XmlReader是一个抽象类,用来读取和解析XML。一个更常用的子类是XmlTextReader,它可以一个结点一个结点的读取XML。XmlReader类提供最快并且占用内存最少的方法来读取和解析XML数据流,该读取只能向前,并且没有缓存。这个类适用于读取很大的XML文件,并且需要的数据在文件里靠前的位置。下面是一个使用XmlReader的例子:
代码语言:javascript复制 private void parsingWithXmlReaderToolStripMenuItem_Click(object sender, EventArgs e)
{
var sb = new StringBuilder();
var xmlReader = new XmlTextReader(getFilePath("XmlDocumentTest.xml"));
while (xmlReader.Read())
{
switch (xmlReader.NodeType)
{
case XmlNodeType.XmlDeclaration:
case XmlNodeType.Element:
case XmlNodeType.Comment:
sb.AppendFormat("{0}: {1} = {2}",
xmlReader.NodeType,
xmlReader.Name,
xmlReader.Value);
sb.AppendLine();
break;
case XmlNodeType.Text:
sb.AppendFormat(" - Value: {0}", xmlReader.Value);
sb.AppendLine();
break;
}
if (xmlReader.HasAttributes)
{
while (xmlReader.MoveToNextAttribute())
{
sb.AppendFormat(" - Attribute: {0} = {1}",
xmlReader.Name,
xmlReader.Value);
sb.AppendLine();
}
}
}
xmlReader.Close();
txtLog.Text = sb.ToString();
}
输出结果如下:
代码语言:javascript复制XmlDeclaration: xml=version="1.0" encoding="utf-8"
Attribute: version=1.0
Attribute: encoding=utf-8
Element: MyRoot=
Element: MyChild=
Attribute: ID=1
Element: MyGrandChild=
Element: MyGrandChild=
Element: MyGrandChild=
Element: MyChild=
Attribute: ID=2
Element: MyGrandChild=
Element: MyGrandChild=
Element: MyGrandChild=
Element: MyChild=
Attribute: ID=3
Element: MyGrandChild=
Element: MyGrandChild=
Element: MyGrandChild=
Element: MyChild=
Attribute: ID=4
Element: MyGrandChild=
Element: MyGrandChild=
Element: MyGrandChild=
三. 小节: • XmlDocument类读取XML结点是全部存在内存中,任意定位,并且可读也可写的。 • XmlReader类读取XML结点使用的是快速数据流(不是一次读取完将数据全部存在内存中),只能向前,只读的。 • XmlDocument类易于使用,而XmlReader类读取效率很高。 • XmlDocument类可以使用元素名来读取XML结点。 • XmlDocument类可以使用XPath来读取结点。
原文出自《Access Data with Microsoft .NET Framework 4》
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/150751.html原文链接:https://javaforall.cn