天天看點

.Net Compact Framework開發(4)——XML DOM操作

  • 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"));