2011-04-09 16 views
30

He escrito un programa de programación de tareas para fines de aprendizaje. Actualmente estoy guardando las tareas programadas solo como texto plano y luego analizando usando Regex. Esto se ve sucio (en cuanto al código) y no es muy coherente.Análisis XML: lea un archivo XML simple y recupere valores

Me gustaría cargar las tareas programadas desde un archivo XML en su lugar, he buscado bastante para encontrar algunas soluciones, pero no pude hacer que funcionara como yo quería.

escribí un archivo XML estructurado como este para almacenar mis datos en:

<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 forma en que me gustaría analizar los datos es de esta manera:

  1. Abre Tareas. xml
  2. Cargue la primera etiqueta de tarea.
  3. En esa tarea recupera los valores de las etiquetas Nombre, Ubicación y Argumentos.
  4. A continuación, abra la etiqueta RunWhen y recupere los valores de las etiquetas de hora y fecha.
  5. Después de eso abra la etiqueta Días y recupere el valor de cada etiqueta individual dentro.
  6. Recupere el valor de Habilitado.
  7. Cargue la siguiente tarea y repita los pasos 3 -> 7 hasta que se hayan analizado todas las etiquetas de tareas en Tareas.

estoy muy seguro de que puede hacerlo de esta manera yo no puedo elaborarlo, ya que hay muchas maneras diferentes de hacer las cosas en XML que me dieron un poco abrumado. Pero lo que he llegado hasta ahora es que lo más probable es que esté usando XPathDocument y XPathNodeIterator ¿verdad?

Si alguien me puede mostrar un ejemplo o explicarme cómo se haría esto, estaría muy feliz.

Respuesta

41

Una forma sencilla de analizar el código XML es utilizar el LINQ to XML

por ejemplo, tiene el siguiente archivo XML

<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> 

Para leer este archivo, puede utilizar el siguiente código:

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); 
    } 
} 
+1

Lo tengo funcionando perfectamente, gracias montones :) – Lucidity

+1

Eso es realmente simple, gracias –

+6

Para aquellos que quieren copiar/pegar este código, estás ' También necesitará agregar "using System.Xml.Linq;" – VenerableAgents

2

¿Está familiarizado con la clase DataSet?

El DataSet también puede documentos load XML y puede que le resulte más fácil de iterar.

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

DataSet dt = new DataSet(); 
dt.ReadXml(@"c:\test.xml"); 
+2

-1: DataTable no puede cargar todo el XML, solo el XML que coincide con el patrón de una base de datos relacional. –

+0

@JohnSaunders - ¿Cuidar para elaborar? Acabo de probar el código anterior con el archivo xml en cuestión y lo lee sin problema – WraithNath

+0

Justo lo que dije. 'DataSet' no puede manejar XML arbitrario. Solo puede manejar XML que se asigna a una estructura "relacional". Muchas cosas "normales" que puede querer usar con XML no funcionarán con 'DataSet'. Por ejemplo, ''. Una tabla relacional no puede tener dos padres, por lo que esto no funcionará con 'DataSet'. –

8

normalmente utilizo para este XmlDocument. La interfaz es bastante simple:

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

Se puede acceder a los nodos similares a un diccionario:

var tasks = doc["Tasks"]; 

y lazo sobre todos los hijos de un nodo.

2

Trate XmlSerialization

probar esto

[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); 
}