在C#解析XML

问题描述:

我正在寻找一种方式来阅读下面的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值的最佳方式是什么?

谢谢

它可以使用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

那么,你可以很容易地阅读使用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

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

我建议你看一看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

创建一个类数据与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