2009-10-22 115 views
1

我正在尋找一種方式來閱讀下面的XML在C#解析XML

<Data> 
    <MaxCount>10</MaxCount> 
    <Points> 
    <Point X="10" Y="10"/> 
    <Point X="20" Y="10"/> 
    <Point X="30" Y="10"/> 
    <Point X="40" Y="10"/> 
    <Point X="50" Y="10"/> 
    <Point X="60" Y="10"/> 
    </Points> 
</Data> 

基本上我想所有的點值讀入Point對象的數組(我點對象有2個屬性X和Y )和MaxCount成一個整數。使用C#從XML文件中提取Point值的最佳方式是什麼?

謝謝

回答

1

它可以使用XPath來完成:

public void CreatePoints(string xml) 
{ 
    XPathDocument doc = new XPathDocument(XmlReader.Create(new StringReader(xml))); 
    var xPathNodeIterator = doc.CreateNavigator().Select("/Data/Points/Point"); 
    foreach (XPathNavigator node in xPathNodeIterator) 
    { 
     var x = node.SelectSingleNode("@X").ValueAsInt; 
     var y = node.SelectSingleNode("@Y").ValueAsInt; 

     new Point(x, y); 
    } 
} 
+0

你可以用doc.LoadXml(xml)讀取XML。在doc變量上,您可以調用doc.DocumentElement.SelectNodes(「Data/Points/*」)並遍歷每個XmlNode。 – 2009-10-22 10:54:51

+0

@Patrick:與XPathDocument相比,XMLDocument是一個非常重的對象。儘管使用XPathDocument有點麻煩,但它的性能要比XMLDocumnet好得多。 – rauts 2009-10-23 08:14:03

4

那麼,你可以很容易地閱讀使用XMLDocument類的文件。

http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx

基本上你只需要讀取文件中的類,然後再循環通過將XMLNode它創建。您可以使用節點的innerText屬性讀取MaxCount,並在您通過其子節點循環並通過XMLNode的屬性屬性獲取所需的數據時。

+0

我寧願使用LINQ-to-XML類(XDocument)來代替... – 2009-10-22 10:46:42

4
class Point 
    { 
     public int X { get; set; } 
     public int Y { get; set; } 
    } 

    static int Main(string[] args) 
    { 
     string xml = "<Data> <MaxCount>10</MaxCount> <Points> <Point X=\"10\" Y=\"10\"/> <Point X=\"20\" Y=\"10\"/> <Point X=\"30\" Y=\"10\"/> <Point X=\"40\" Y=\"10\"/> <Point X=\"50\" Y=\"10\"/> <Point X=\"60\" Y=\"10\"/> </Points></Data>"; 

     XDocument doc = XDocument.Parse(xml); 

     int maxCount = int.Parse(doc.Element("Data").Element("MaxCount").Value); 

     var points = from e in doc.Element("Data").Element("Points").Elements("Point") 
        select new Point 
        { 
         X = int.Parse(e.Attribute("X").Value), 
         Y = int.Parse(e.Attribute("Y").Value) 
        }; 

     Console.WriteLine("MaxCount: {0}", maxCount); 
     foreach (var item in points) 
     { 
      Console.WriteLine("Point: {0},{1}", item.X, item.Y); 
     } 
    } 
+0

+1,linq to xml是一個很棒的工具。 – chester89 2009-10-22 11:54:42

8

我建議你看一看XmlSerializer類。它允許您直接將XML序列化並反序列化爲對象。

首先,類來表示你的數據:

[XmlRoot(Namespace = "")] 
public class Data 
{ 
    public int MaxCount; 
    public Point[] Points; 
} 

public class Point 
{ 
    [XmlAttribute] 
    public int X; 
    [XmlAttribute] 
    public int Y; 
} 

然後你使用XmlSerializer:

Stream s = ... // Some code to open you file into a stream 

var serializer = new XmlSerializer(typeof(Data)); 
Data d = (Data)serializer.Deserialize(s); 

文章:http://msdn.microsoft.com/en-us/library/ms950721.aspx

+1

爲了獲得獎勵,您可以使用xsd.exe爲您自動創建此類http://msdn.microsoft.com/en-us/library/x6c1kb0s%28VS.71%29.aspx – Lee 2009-10-22 11:16:52

+0

@李:偉大的提示。我已經忘記了這一點。 (有一段時間沒有使用它...) – 2009-10-22 11:20:36

0

創建一個類數據與MAXCOUNT整數屬性和一個屬性List類型的點(Point是具有X和Y屬性的另一個類)。將這些類標記爲Serializable。

在XMLReader中加載Xml。

反序列化Xml在Data類中使用Xmlreader。

對不起,沒有提供一個工作的例子。

+0

我覺得這裏的矯枉過正。爲這個簡單的場景使用XPath。 – 2009-10-22 11:46:52

+0

@帕特里克:不過分;-)已經有一個他想要填充的點類。爲了便於閱讀/複雜性和代碼量,請參閱我上面的答案... – 2009-10-22 12:05:36