web-dev-qa-db-fra.com

Analyse XML - Lire un fichier XML simple et récupérer des valeurs

J'ai écrit un programme de planification des tâches à des fins d'apprentissage. Actuellement, j'enregistre les tâches planifiées sous forme de texte brut, puis je les analyse à l'aide de Regex. Cela semble compliqué (en termes de code) et n’est pas très cohérent. 

J'aimerais plutôt charger les tâches planifiées à partir d'un fichier XML. J'ai un peu cherché à trouver des solutions, mais je n'ai pas réussi à le faire fonctionner comme je le voulais. 

J'ai écrit un fichier XML structuré comme ceci pour stocker mes données dans:

<Tasks>
    <Task>
        <Name>Shutdown</Name>
        <Location>C:/WINDOWS/system32/shutdown.exe</Location>
        <Arguments>-s -f -t 30</Arguments>
        <RunWhen>
            <Time>8:00:00 a.m.</Time>
            <Date>18/03/2011</Date>
            <Days>
                <Monday>false</Monday>
                <Tuesday>false</Tuesday>
                <Wednesday>false</Wednesday>
                <Thursday>false</Thursday>
                <Friday>false</Friday>
                <Saturday>false</Saturday>
                <Sunday>false</Sunday>
                <Everyday>true</Everyday>
                <RunOnce>false</RunOnce>
            </Days>
        </RunWhen>
        <Enabled>true</Enabled>
    </Task>
</Tasks>

La façon dont je voudrais analyser les données est la suivante:

  1. Ouvrir Tasks.xml 
  2. Chargez la première étiquette de tâche.
  3. Dans cette tâche, récupérez les valeurs des balises Name, Location et Arguments.
  4. Ouvrez ensuite la balise RunWhen et récupérez les valeurs des balises Time et Date.
  5. Après cela, ouvrez la balise Days et récupérez la valeur de chaque balise au sein de celle-ci.
  6. Récupérer la valeur de Enabled.
  7. Chargez la tâche suivante et répétez les étapes 3 -> 7 jusqu'à ce que toutes les balises de tâche dans Tâches aient été analysées.

Je suis persuadé que vous pouvez le faire de cette façon. Je ne peux tout simplement pas y arriver car il y a tellement de façons différentes de faire des choses en XML que je suis un peu dépassé. Mais ce que j’ai fait jusqu’à présent, c’est que j’utiliserais probablement XPathDocument et XPathNodeIterator, non?

Si quelqu'un pouvait me montrer un exemple ou m'expliquer comment cela se ferait, je serais très heureux.

30
Lucidity

Un moyen simple d'analyser le XML est d'utiliser le LINQ to XML

par exemple, vous avez le fichier XML suivant

<library>
    <track id="1" genre="Rap" time="3:24">
        <name>Who We Be RMX (feat. 2Pac)</name>
        <artist>DMX</artist>
        <album>The Dogz Mixtape: Who's Next?!</album>
    </track>
    <track id="2" genre="Rap" time="5:06">
        <name>Angel (ft. Regina Bell)</name>
        <artist>DMX</artist>
        <album>...And Then There Was X</album>
    </track>
    <track id="3" genre="Break Beat" time="6:16">
        <name>Dreaming Your Dreams</name>
        <artist>Hybrid</artist>
        <album>Wide Angle</album>
    </track>
    <track id="4" genre="Break Beat" time="9:38">
        <name>Finished Symphony</name>
        <artist>Hybrid</artist>
        <album>Wide Angle</album>
    </track>
<library>

Pour lire ce fichier, vous pouvez utiliser le code suivant:

public void Read(string  fileName)
{
    XDocument doc = XDocument.Load(fileName);

    foreach (XElement el in doc.Root.Elements())
    {
        Console.WriteLine("{0} {1}", el.Name, el.Attribute("id").Value);
        Console.WriteLine("  Attributes:");
        foreach (XAttribute attr in el.Attributes())
            Console.WriteLine("    {0}", attr);
        Console.WriteLine("  Elements:");

        foreach (XElement element in el.Elements())
            Console.WriteLine("    {0}: {1}", element.Name, element.Value);
    }
}
44
Serghei

J'utilise habituellement XmlDocument pour cela. L'interface est assez simple:

var doc = new XmlDocument();
doc.LoadXml(xmlString);

Vous pouvez accéder à des nœuds similaires à un dictionnaire:

var tasks = doc["Tasks"];

et boucle sur tous les enfants d'un noeud.

10
ChrisWue

Essayez XmlSerialization

essaye ça 

[Serializable]
public class Task
{
    public string Name{get; set;}
    public string Location {get; set;}
    public string Arguments {get; set;}
    public DateTime RunWhen {get; set;}
}

public void WriteXMl(Task task)
{
    XmlSerializer serializer;
    serializer = new XmlSerializer(typeof(Task));

    MemoryStream stream = new MemoryStream();

    StreamWriter writer = new StreamWriter(stream, Encoding.Unicode);
    serializer.Serialize(writer, task);

    int count = (int)stream.Length;

     byte[] arr = new byte[count];
     stream.Seek(0, SeekOrigin.Begin);

     stream.Read(arr, 0, count);

     using (BinaryWriter binWriter=new BinaryWriter(File.Open(@"C:\Temp\Task.xml", FileMode.Create)))
     {
         binWriter.Write(arr);
     }
 }

 public Task GetTask()
 {
     StreamReader stream = new StreamReader(@"C:\Temp\Task.xml", Encoding.Unicode);
     return (Task)serializer.Deserialize(stream);
 }
2
BreakHead

Connaissez-vous la classe DataSet?

Les DataSet peuvent aussi load documents XML et il vous sera peut-être plus facile de les parcourir.

http://msdn.Microsoft.com/en-us/library/system.data.dataset.readxml.aspx

DataSet dt = new DataSet();
dt.ReadXml(@"c:\test.xml");
2
WraithNath
class Program
{

    static void Main(string[] args)
    {

        //Load XML from local
        string sourceFileName="";
        string element=string.Empty;
        var FolderPath=@"D:\Test\RenameFileWithXmlAttribute";

            string[] files = Directory.GetFiles(FolderPath, "*.xml");
            foreach (string xmlfile in files)
            {
                try
                {
                    sourceFileName = xmlfile;
                    XElement xele = XElement.Load(sourceFileName);
                    string convertToString = xele.ToString();
                    XElement parseXML = XElement.Parse(convertToString);
                    element = parseXML.Descendants("Meta").Where(x => (string)x.Attribute("name") == "XMLTAG").Last().Value;
                    DirectoryInfo CurrentDate = Directory.CreateDirectory(DateTime.Now.ToString("yyyy-MM-dd"));
                    string saveWithThisName= Path.Combine(CurrentDate.FullName, element);
                    File.Copy(sourceFileName, saveWithThisName,true);                      
                }
                catch(Exception ex)
                {

                }      
            }       
    }
}
0
DivyaPrakash