.Net Compact Framework开发(4)——XML DOM操作

来源:互联网 发布:北京有mac专柜吗 编辑:程序博客网 时间:2022/05/27 13:34
  • 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>");
  • 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;
  }
}
  • XmlNode也可以直接使用Indexer来获取子节点;
XmlDocument doc = new XmlDocument();
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);
  • 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);

  • 如果想获得更好的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);
      }
    }
  }
}
  • 如果是从头开始创建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);
  • 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");
  • 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");
  • 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");
  • 可以使用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");
  • 可以使用RemoveChild和RemoveAll方法来删除现有节点;
XmlDocument doc = new XmlDocument();
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");
  • 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);
  • 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"));