2009-10-22 7 views
1

Je cherche un moyen de lire le code XML suivantParsing XML en 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> 

Fondamentalement, je veux lire toutes les valeurs de point dans un tableau d'objets Point (Mon objet point a 2 propriétés X et Y) et le MaxCount dans un entier. Quelle est la meilleure façon de retirer les valeurs de point du fichier XML en utilisant C#?

Merci

Répondre

1

Il peut être fait en utilisant 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

Vous pouvez lire XML en 1 go avec doc.LoadXml (xml). Sur la variable doc, vous pouvez appeler doc.DocumentElement.SelectNodes ("Data/Points/*") et parcourir chaque XmlNode. –

+0

@Patrick: XMLDocument est un objet très lourd par rapport à XPathDocument. Bien qu'il soit peu pratique d'utiliser XPathDocument, ses performances sont bien meilleures que XMLDocumnet. – rauts

4

Eh bien, vous pouvez facilement lire le fichier en utilisant la classe XMLDocument.

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

Fondamentalement, vous aurait tout simplement avoir la classe lu dans le fichier, puis ensuite faire défiler les XMLNodes qu'il crée. Vous liriez dans le MaxCount en utilisant la propriété innerText du nœud, et lorsque vous atteindriez cycliquement ses enfants et saisiriez les données dont vous avez besoin via la propriété d'attribut du XMLNode.

+0

Je préférerais utiliser des classes LINQ-to-XML (XDocument) à la place ... –

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 est un excellent outil pour cela – chester89

8

Je vous suggère de jeter un oeil à la classe XmlSerializer. Il vous permet de sérialiser et de désérialiser le XML directement aux objets.

D'abord, les classes pour représenter vos données:

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

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

Ensuite, vous utilisez XmlSerializer:

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

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

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

+1

Pour un bonus, vous pouvez utiliser xsd.exe pour créer automagiquement cette classe pour vous http://msdn.microsoft.com/en-us/library/x6c1kb0s%28VS.71%29.aspx – Lee

+0

@Lee: Bon conseil. J'avais oublié ça. (N'a pas eu l'usage pendant un moment ...) –

0

Créer une propriété entière de données de classe avec MaxCount et un property Points de type List (Point est une autre classe avec les propriétés X et Y). Marquez ces classes comme Serializable.

Chargez le fichier XML dans XMLReader. Deserialize the Xml Utilisation du Xmlreader dans la classe Data.

Désolé de ne pas fournir d'exemple.

+0

Overkill ici je pense. Utilisez XPath pour ce scénario simple. –

+0

@Patrick: Pas trop ;-) Il y a déjà une classe de points qu'il veut peupler. Pour la lisibilité/complexité et la quantité de code, voir ma réponse ci-dessus ... –