2009-10-22 6 views
1

Я ищу способ прочитать следующие XMLСинтаксический XML в C#

<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 в целое число. Каков наилучший способ вытащить значения Point из файла XML с помощью C#?

Благодаря

ответ

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

Вы можете прочитать XML в 1 go с doc.LoadXml (xml). На doc variabele вы можете вызвать doc.DocumentElement.SelectNodes («Данные/Точки/*») и выполнить итерацию каждого XmlNode. –

+0

@Patrick: XMLDocument является очень тяжелым весовым объектом по сравнению с XPathDocument. Хотя использование XPathDocument довольно громоздко, его производительность намного лучше, чем XMLDocumnet. – rauts

4

Ну, вы могли бы легко прочитать файл с помощью класса XMLDocument.

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

В основном вы просто класс прочитать в файле, а затем затем цикл через XMLNodes, что он создает. Вы читали в MaxCount, используя свойство innerText узла, и когда вы достигаете цикла через своих детей и захватываете данные, необходимые вам с помощью свойства атрибута XMLNode.

+0

Я бы предпочел использовать LINQ-to-XML классы (XDocument) вместо ... –

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

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

+0

@Lee: Отличный совет. Я забыл про это. (Не использовал для этого какое-то время ...) –

0

Создать класс данных с MAXCOUNT целочисленное свойство и один свойство Точки типа List (Point - это еще один класс с свойствами X и Y). Отметьте эти классы как Serializable.

Загрузите Xml в XMLReader.

Deserialize Xml Использование Xmlreader в классе Data.

Извините за отсутствие рабочего примера.

+0

Overkill здесь я думаю. Используйте XPath для этого простого сценария. –

+0

@Patrick: Не перебор ;-) Там уже есть класс очков, который он хочет заселить. Для удобства чтения/сложности и количества кода см. Мой ответ выше ... –

Смежные вопросы