2013-05-10 181 views
2

我有一個代碼讀取一個XML文件。有一些我不明白的地方。 從我的理解,代碼將創建一個包含2個元素的012文件, 「Product」和「OtherDetails」。我們怎麼只需要使用writer.WriteEndElement(); 曾經當我們使用writer.WriteStartElement兩次? ,不應該用writer.WriteEndElement()語句關閉每個 writer.WriteStartElement語句嗎?如何在C#中讀取xml文件?

using System.Xml; 

public class Program 
{ 
    public static void Main() 
    { 
     XmlWriterSettings settings = new XmlWriterSettings(); 
     settings.Indent = true; 

     XmlWriter writer = XmlWriter.Create("Products.xml", settings); 
     writer.WriteStartDocument(); 
     writer.WriteComment("This file is generated by the program."); 
     writer.WriteStartElement("Product");   // first s 
     writer.WriteAttributeString("ID", "001"); 
     writer.WriteAttributeString("Name", "Soap"); 
     writer.WriteElementString("Price", "10.00") 

     // Second Element 
     writer.WriteStartElement("OtherDetails"); 
     writer.WriteElementString("BrandName", "X Soap"); 
     writer.WriteElementString("Manufacturer", "X Company"); 
     writer.WriteEndElement(); 
     writer.WriteEndDocument(); 

     writer.Flush(); 
     writer.Close(); 
    } 
} 
using System; 
using System.Xml; 

public class Program 
{ 
    public static void Main() 
    { 
     XmlReader reader = XmlReader.Create("Products.xml"); 

     while (reader.Read()) 
     { 
      if (reader.NodeType == XmlNodeType.Element 
      && reader.Name == "Product") 
      { 
       Console.WriteLine("ID = " + reader.GetAttribute(0)); 
       Console.WriteLine("Name = " + reader.GetAttribute(1)); 

       while (reader.NodeType != XmlNodeType.EndElement) 
       { 
        reader.Read(); 
        if (reader.Name == "Price") 
        { 
         while (reader.NodeType != XmlNodeType.EndElement) 
         { 
          reader.Read(); 
          if (reader.NodeType == XmlNodeType.Text) 
          { 
           Console.WriteLine("Price = {0:C}", Double.Parse(reader.Value)); 
          } 
         } 

         reader.Read(); 

        } //end if 


        if (reader.Name == "OtherDetails") 
        { 
         while (reader.NodeType != XmlNodeType.EndElement) 
         { 
          reader.Read(); 
          if (reader.Name == "BrandName") 
          { 
           while (reader.NodeType != XmlNodeType.EndElement) 
           { 
            reader.Read(); 
            if (reader.NodeType == XmlNodeType.Text) 
            { 
             Console.WriteLine("Brand Name = " + reader.Value); 
            } 
           } 
           reader.Read(); 
          } //end if 

          if (reader.Name == "Manufacturer") 
          { 
           while (reader.NodeType != XmlNodeType.EndElement) 
           { 
            reader.Read(); 
            if (reader.NodeType == XmlNodeType.Text) 
            { 
             Console.WriteLine("Manufacturer = " + reader.Value); 
            } 
           } 

          } //end if 
         } 
        } //end if 
       } //end while 
      } //end if 

     } //end while 
    } 
} 

我沒有得到這個部分:

if (reader.Name == "OtherDetails") 
{ 
    while (reader.NodeType != XmlNodeType.EndElement) 
    { 
     reader.Read(); 
     if (reader.Name == "BrandName") 
     { 
      while (reader.NodeType != XmlNodeType.EndElement) 
      { 
       reader.Read(); 
       if (reader.NodeType == XmlNodeType.Text) 
       { 
        Console.WriteLine("Brand Name = " + reader.Value); 
       } 
      } 

通知如何病情while (reader.NodeType != XmlNodeType.EndElement)已經被使用了兩次?

這是爲什麼我們沒有指定

if (reader.NodeType == XmlNodeType.Element for OtherDetails),因爲我們沒有爲產品,

這樣

if (reader.NodeType == XmlNodeType.Element 
&& reader.Name == "OtherDetails") 
{} 
+11

你*有*使用的XmlWriter?如果你可以使用LINQ to XML,那麼編碼就會簡單得多。 – 2013-05-10 20:00:21

+1

我更喜歡使用XmlDocument來讀取XML文件。您可以輕鬆循環遍歷每個節點和每個節點的子節點。 – 2013-05-10 20:11:39

+0

@HH你有沒有試過Linq2Xml?你所說的所有事情都可以做得更容易。 – I4V 2013-05-10 20:13:23

回答

3

要回答你的第一個問題:

由於MSDN documentation for XmlWriter.WriteEndDocument()說:

關閉所有打開的元素或屬性,並將寫入器重新置於「開始」狀態。

因此它會自動關閉任何打開的元素給你。實際上,您可以完全刪除對WriteEndElement()的呼叫,它仍然可以正常工作。

正如人們在上面的評論中所說的,你應該考慮使用Linq-to-XML。

它可以讓事情變得更容易。例如,使用LINQ到XML,你可以做到這一點創建程序的XML結構:

var doc = new XDocument(
    new XElement("Product", 
      new XAttribute("ID", "001"), new XAttribute("Name", "Soap"), 
     new XElement("Price", 10.01), 
     new XElement("OtherDetails", 
      new XElement("BrandName", "X Soap"), 
      new XElement("Manufacturer", "X Company")))); 

File.WriteAllText("Products.xml", doc.ToString()); 

如果您是從XML讀取數據時,您可以使用var doc = XDocument.Load("Filename.xml")從文件加載XML,然後獲取數據出來很簡單,只要:

double price  = double.Parse(doc.Descendants("Price").Single().Value); 
string brandName = doc.Descendants("BrandName").Single().Value; 

或可替代(鑄造):

double price  = (double) doc.Descendants("Price").Single(); 
string brandName = (string) doc.Descendants("BrandName").Single(); 

(如果你想知道我們如何在地球上可以投射型的XElement L的對象邁克說:這是因爲a load of explict conversion operators are defined for XElement

0

如果你需要什麼東西兩岸向前(無閱讀或研究),這裏是我做過什麼:

我最近寫了一個自定義的XML解析方法爲我的MenuStrip對的WinForms(它有數百個項目,XML是我最好的選擇)。

// load the document 
// I loaded mine from my C# resource file called TempResources 
XDocument doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(TempResources.Menu))); 

// get the root element 
// (var is an auto token, it becomes what ever you assign it) 
var elements = doc.Root.Elements(); 

// iterate through the child elements 
foreach (XElement node in elements) 
{ 
    // if you know the name of the attribute, you can call it 
    // mine was 'name' 
    // (if you don't know, you can call node.Attributes() - this has the name and value) 
    Console.WriteLine("Loading list: {0}", node.Attribute("name").Value); 

    // in my case, every child had additional children, and them the same 
    // *.Cast<XElement>() would give me the array in a datatype I can work with 
    // menu_recurse(...) is just a resursive helper method of mine 
    menu_recurse(node.Elements().Cast<XElement>().ToArray())); 
} 

(我的回答也可以在這裏找到:Reading an XML File With Linq - 儘管這不幸的是,不是LINQ)

0

假設,如果你想讀的,我們需要使用一個數據集的XML文件,因爲XML文件在內部轉換使用數據集將其轉換爲數據表。使用以下代碼行訪問文件並將數據集與xml數據綁定。

DataSet ds=new DataSet(); 
    ds.ReadXml(HttpContext.Current.Server.MapPath("~/Labels.xml"); 

數據集包括許多數據表中,這些數據表的數量取決於親子標籤的數量在一個XML文件