- XML DOM(Document Object Model)在内存中创建了XML文档的树状视图,可以在任意方向访问访问,可以用于创建、修改、解析XML文档;XML DOM树是由XmlNode组成的;
- XmlDocument指示了XML DOM树的最顶层,其DocumentElement属性指示了树的根节点;
- 要想向XmlDocument中装入XML,可以使用Load方法从Stream, TextReader, 或XmlReader装入,也可以直接使用LoadXml方法从XML string装入;
// Load the document from a stream
XmlDocument doc = new XmlDocument();
doc.Load(new FileReader("bogus.xml", FileMode.Open));
// Load the document from a TextReader
doc = new XmlDocument();
doc.Load(new StreamReader("bogus.xml"));
// Load the document from a XmlReader
doc = new XmlDocument();
doc.Load(new XmlTextReader("bogus.xml");
// Load the document for an XML string
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root><child/></root>");
XmlDocument doc = new XmlDocument();
doc.Load(new FileReader("bogus.xml", FileMode.Open));
// Load the document from a TextReader
doc = new XmlDocument();
doc.Load(new StreamReader("bogus.xml"));
// Load the document from a XmlReader
doc = new XmlDocument();
doc.Load(new XmlTextReader("bogus.xml");
// Load the document for an XML string
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root><child/></root>");
- XmlNode提供HasChildNodes属性来指示是否具有子节点,使用ChildNodes属性来返回子节点的列表;提供了FirstChild和LastChild属性来跳转到头尾子节点;提供了NextSibling和PreviousSibling属性来跳转到前后兄弟节点;提供了ParentNode属性来跳转到父节点;提供了OwnerDocument来表示DocumentElement的父节点
void DepthFirst(XmlNode node)
{
// Visit the node
MessageBox.Show("Name: " + node.Name);
if(!node.HasChildNodes)
{
foreach(XmlNode child in node.ChildNodes)
DepthFirst(child);
}
}
等效于
static void DepthFirst(XmlNode node)
{
// Visit the node
MessageBox.Show("Name: " + node.Name);
if(node.HasChildNodes)
{
for(int i = 0; i < node.ChildNodes.Count; ++i)
DepthFirst(node.ChildNodes[i]);
}
}
等效于
void DepthFirst(XmlNode node)
{
// Visit the node
MessageBox.Show("NodeType: " + node.NodeType);
XmlNode child = node.FirstChild;
while(child != null)
{
DepthFirst(child);
child = child.NextSibling;
}
}
{
// Visit the node
MessageBox.Show("Name: " + node.Name);
if(!node.HasChildNodes)
{
foreach(XmlNode child in node.ChildNodes)
DepthFirst(child);
}
}
等效于
static void DepthFirst(XmlNode node)
{
// Visit the node
MessageBox.Show("Name: " + node.Name);
if(node.HasChildNodes)
{
for(int i = 0; i < node.ChildNodes.Count; ++i)
DepthFirst(node.ChildNodes[i]);
}
}
等效于
void DepthFirst(XmlNode node)
{
// Visit the node
MessageBox.Show("NodeType: " + node.NodeType);
XmlNode child = node.FirstChild;
while(child != null)
{
DepthFirst(child);
child = child.NextSibling;
}
}
- XmlNode也可以直接使用Indexer来获取子节点;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root><child1/><child2/></root>");
Console.WriteLine(doc.DocumentElement["child2"].Name);
doc.LoadXml("<root><child1/><child2/></root>");
Console.WriteLine(doc.DocumentElement["child2"].Name);
- XmlNode可以使用InnerText或者Value来返回Element的文本,前者返回当前节点和所有子节点的文本的连接结果;后者只能在当前element只包含string数据的时候使用;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<Book>" +
"<Title>Catcher in the Rye</Title>" +
"<Price>25.98</Price>" +
"</Book>");
MessageBox.Show("Price: " +
doc.DocumentElement["Price"].InnerText);
MessageBox.Show("Price: " +
doc.DocumentElement["Price"].FirstChild.Value);
doc.LoadXml("<Book>" +
"<Title>Catcher in the Rye</Title>" +
"<Price>25.98</Price>" +
"</Book>");
MessageBox.Show("Price: " +
doc.DocumentElement["Price"].InnerText);
MessageBox.Show("Price: " +
doc.DocumentElement["Price"].FirstChild.Value);
- XmlNode也可以使用InnerXml和OuterXml属性将节点的内容(含XML markup)全部返回;
- XmlNode通过Attributes属性返回AttributeCollection列表,既可以通过foreach遍历,也可以通过Count属性或Indexer访问;XmlAttribute主要使用Name和Value属性;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root att1=/"val1/" att2=/"val2/" />");
XmlNode node = doc.DocumentElement;
foreach(XmlAttribute att in node.Attributes)
{
MessageBox.Show(att.Name + ":" + att.Value);
}
for(int ndx = 0; ndx < node.Attributes.Count; ++ndx)
{
XmlAttribute att = node.Attributes[ndx];
MessageBox.Show(att.Name + ":" + att.Value);
}
XmlAttribute att = node.Attributes["att1"];
MessageBox.Show(att.Name + ":" + att.Value);
doc.LoadXml("<root att1=/"val1/" att2=/"val2/" />");
XmlNode node = doc.DocumentElement;
foreach(XmlAttribute att in node.Attributes)
{
MessageBox.Show(att.Name + ":" + att.Value);
}
for(int ndx = 0; ndx < node.Attributes.Count; ++ndx)
{
XmlAttribute att = node.Attributes[ndx];
MessageBox.Show(att.Name + ":" + att.Value);
}
XmlAttribute att = node.Attributes["att1"];
MessageBox.Show(att.Name + ":" + att.Value);
- 如果想获得更好的attribute属性访问能力,可以使用XmlElement类,其提供HasAttributes属性来指示是否有属性,使用HasAttribute方法来判断是否有特定的Attribute;
XmlDocument doc = New XmlDocument();
doc.LoadXml("<root att1=/"val1/" att2=/"val2/" />");
XmlElement elem = doc.DocumentElement;
MessageBox.Show("Contains Attributes: " + elem.HasAttributes);
MessageBox.Show("Contains att1: " + elem.HasAttribute("att1"));
XmlDocument和XmlElement类提供了GetElementsByTagName方法来按照element的Name查找Node;
public static void Main()
{
XmlDocument doc = new XmlDocument();
StreamReader s = new StreamReader("input.xml", Encoding.UTF8);
doc.Load(s);
s.Close();
XmlNodeList authors = doc.GetElementsByTagName("Author");
foreach(XmlElement author in authors)
{
if(author.GetAttribute("Name") == "John Doe")
{
XmlNodeList books = doc.GetElementsByTagName("Book");
foreach(XmlElement book in books)
{
MessageBox.Show(book.FirstChild.InnerText);
}
}
}
}
doc.LoadXml("<root att1=/"val1/" att2=/"val2/" />");
XmlElement elem = doc.DocumentElement;
MessageBox.Show("Contains Attributes: " + elem.HasAttributes);
MessageBox.Show("Contains att1: " + elem.HasAttribute("att1"));
XmlDocument和XmlElement类提供了GetElementsByTagName方法来按照element的Name查找Node;
public static void Main()
{
XmlDocument doc = new XmlDocument();
StreamReader s = new StreamReader("input.xml", Encoding.UTF8);
doc.Load(s);
s.Close();
XmlNodeList authors = doc.GetElementsByTagName("Author");
foreach(XmlElement author in authors)
{
if(author.GetAttribute("Name") == "John Doe")
{
XmlNodeList books = doc.GetElementsByTagName("Book");
foreach(XmlElement book in books)
{
MessageBox.Show(book.FirstChild.InnerText);
}
}
}
}
- 如果是从头开始创建XMLDocument,可能想要创建一个XmlDeclaration节点,这使用XmlDocument的CreateXmlDeclaration方法;CreateXmlDeclaration有三个参数,分别是版本号、编码方式(可以为null或String.Empty)、是否standalone(可以为null或String.Empty);
// <?xml version="1.0" encoding="ASCII" standalone="yes"?>
XmlDeclaration decl = XmlDeclaration("1.0", "ASCII", "yes");
// <?xml version="1.0" encoding="UTF8"?>
decl = XmlDeclaration("1.0", "UTF8", null);
// <?xml version="1.0"?>
decl = XmlDeclaration("1.0", null, null);
XmlDeclaration decl = XmlDeclaration("1.0", "ASCII", "yes");
// <?xml version="1.0" encoding="UTF8"?>
decl = XmlDeclaration("1.0", "UTF8", null);
// <?xml version="1.0"?>
decl = XmlDeclaration("1.0", null, null);
- XmlDocument提供了CreateElement方法来创建一个XmlElement;
XmlElement newElement = xmlDoc.CreateElement("Book");
- XmlDocument提供了CreateAttribute方法来创建XmlAttribute;在创建Attribute后,必须使用XmlElement的SetAttributeNode方法来关联,SetAttributeNode也可以用于直接创建Attribute,然后赋值;另外还可以SetAttribute方法来直接创建并赋值;
XmlAttribute newAttribute = XmlDoc.CreateAttribute("att");
newAttribute.Value = "val";
XmlAttribute newAttribute = element.SetAttributeNode("att", null);
newAttribute.Value = "val";
element.SetAttribute("title", "Going Back to Cali");
XmlDocument提供了AppendChild和PrependChild方法来向向当前节点添加子节点;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root/>");
XmlElement firstChild = doc.CreateElement("", "First", "");
XmlElement lastChild = doc.CreateElement("", "Last", "");
doc.DocumentElement.PrependChild(firstChild);
doc.DocumentElement.AppendChild(lastChild);
doc.Save("out.xml");
newAttribute.Value = "val";
XmlAttribute newAttribute = element.SetAttributeNode("att", null);
newAttribute.Value = "val";
element.SetAttribute("title", "Going Back to Cali");
XmlDocument提供了AppendChild和PrependChild方法来向向当前节点添加子节点;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root/>");
XmlElement firstChild = doc.CreateElement("", "First", "");
XmlElement lastChild = doc.CreateElement("", "Last", "");
doc.DocumentElement.PrependChild(firstChild);
doc.DocumentElement.AppendChild(lastChild);
doc.Save("out.xml");
- AppendChild和PrependChild只能添加当前Document内的Node,如果需要引入其他Document的Node,可以使用XmlDocument.ImportNode方法;
- 如果要在Child list的中间插入Node,可以使用InsertBefore和InsertAfter方法;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root><first/><last/></root>");
XmlNode first = doc.DocumentElement.FirstChild;
XmlNode last = doc.DocumentElement.LastChild;
XmlElement secondChild = doc.CreateElement("", "second", "");
XmlElement thirdChild = doc.CreateElement("", "third", "");
doc.DocumentElement.InsertAfter(secondChild, first);
doc.DocumentElement.InsertBefore(thirdChild, last);
doc.Save("blah.xml");
doc.LoadXml("<root><first/><last/></root>");
XmlNode first = doc.DocumentElement.FirstChild;
XmlNode last = doc.DocumentElement.LastChild;
XmlElement secondChild = doc.CreateElement("", "second", "");
XmlElement thirdChild = doc.CreateElement("", "third", "");
doc.DocumentElement.InsertAfter(secondChild, first);
doc.DocumentElement.InsertBefore(thirdChild, last);
doc.Save("blah.xml");
- XmlAttributes除了可以被插入到XmlElement外,还可以使用Append、Prepend、InsertBefore、InsertAfter方法插入到XmlAttributeCollection中;如果当前集合内有同名的XmlAttributes,新添加的会覆盖原有的;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root/>");
XmlAttribute first = doc.CreateAttribute("att1");
first.Value = "first";
XmlAttribute second= doc.CreateAttribute("att2");
second.Value = "second";
另一个例子
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root att1=/"first/" att4=/"last/"/>");
XmlAttribute second = doc.CreateAttribute("att2");
second.Value = "2nd";
XmlAttribute third = doc.CreateAttribute("att3");
third.Value = "3rd";
XmlAttributeCollection atts = doc.DocumentElement.Attributes;
XmlAttribute first = atts[0];
XmlAttribute last = atts[1];
atts.InsertAfter(second, first);
atts.InsertBefore(third, last);
doc.Save("blah.xml");
doc.LoadXml("<root/>");
XmlAttribute first = doc.CreateAttribute("att1");
first.Value = "first";
XmlAttribute second= doc.CreateAttribute("att2");
second.Value = "second";
另一个例子
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root att1=/"first/" att4=/"last/"/>");
XmlAttribute second = doc.CreateAttribute("att2");
second.Value = "2nd";
XmlAttribute third = doc.CreateAttribute("att3");
third.Value = "3rd";
XmlAttributeCollection atts = doc.DocumentElement.Attributes;
XmlAttribute first = atts[0];
XmlAttribute last = atts[1];
atts.InsertAfter(second, first);
atts.InsertBefore(third, last);
doc.Save("blah.xml");
- 可以使用ReplaceChild方法来替换Document内现有的节点;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root att1=/"first/" att4=/"last/"/>");
XmlElement newRoot = doc.CreateElement("NewRoot");
doc.ReplaceChild(newRoot, doc.DocumentElement);
doc.Save("blah.xml");
doc.LoadXml("<root att1=/"first/" att4=/"last/"/>");
XmlElement newRoot = doc.CreateElement("NewRoot");
doc.ReplaceChild(newRoot, doc.DocumentElement);
doc.Save("blah.xml");
- 可以使用RemoveChild和RemoveAll方法来删除现有节点;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root><child/></root>");
doc.DocumentElement.RemoveChild(doc.DocumentElement.FirstChild);
doc.DocumentElement.RemoveAll();
doc.Save("out.xml");
doc.LoadXml("<root><child/></root>");
doc.DocumentElement.RemoveChild(doc.DocumentElement.FirstChild);
doc.DocumentElement.RemoveAll();
doc.Save("out.xml");
- XmlAttributeCollection可以使用Remove、RemoveAt和RemoveAll来删除Attributes;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root><child att1=/"val/" " +
"att2=/"val/"/><child att=/"val/" "+
"att3=/"val/"/></root>");
XmlAttributeCollection atts =
doc.DocumentElement.FirstChild.Attributes;
atts.Remove(atts[0]);
atts.RemoveAt(0);
atts = doc.DocumentElement.LastChild.Attributes;
atts.RemoveAll();
doc.Save("out.xml");
doc.LoadXml("<root><child att1=/"val/" " +
"att2=/"val/"/><child att=/"val/" "+
"att3=/"val/"/></root>");
XmlAttributeCollection atts =
doc.DocumentElement.FirstChild.Attributes;
atts.Remove(atts[0]);
atts.RemoveAt(0);
atts = doc.DocumentElement.LastChild.Attributes;
atts.RemoveAll();
doc.Save("out.xml");
- XmlElement可以使用RemoveAttributeNode、RemoveAttributeAt、RemoveAllAttributes方法来删除Attributes;
XmlDocument doc = new XmlDocument();
doc.LoadXml("<root><child att1=/"val/" " +
"att2=/"val/" att3=/"val/"/> " +
"<child att=/"val/" "+
"att3=/"val/"/></root>");
XmlElement firstChild = (XmlElement)doc.DocumentElement.FirstChild;
XmlAttributeCollection atts = firstChild.Attributes;
firstChild.RemoveAttributeNode(atts[0]);
firstChild.RemoveAttribute("att2");
firstChild.RemoveAttributeAt(0);
doc.LoadXml("<root><child att1=/"val/" " +
"att2=/"val/" att3=/"val/"/> " +
"<child att=/"val/" "+
"att3=/"val/"/></root>");
XmlElement firstChild = (XmlElement)doc.DocumentElement.FirstChild;
XmlAttributeCollection atts = firstChild.Attributes;
firstChild.RemoveAttributeNode(atts[0]);
firstChild.RemoveAttribute("att2");
firstChild.RemoveAttributeAt(0);
- XmlDocument提供了Save方法来将内容存储到file、Stream、TextWriter和XmlWriter;
doc.Save("books.xml");
doc.Save(new FileStream("books.xml", FileMode.Open));
doc.Save(new StreamWriter("books.xml"));
doc.Save(new XmlTextWriter("books.xml"));
doc.Save(new FileStream("books.xml", FileMode.Open));
doc.Save(new StreamWriter("books.xml"));
doc.Save(new XmlTextWriter("books.xml"));