2011-01-14 13 views
5

He estado leyendo sobre hebras antiguas aquí, así como las páginas que encontré en Google, y puedo decir honestamente que esto me ha confundido por completo. Parece que hay alrededor de 1000 formas de analizar cadenas XML utilizando C# .NET y no sé cuál usar. Parece que todos los ejemplos que encuentro dependen de un nodo raíz específico y así sucesivamente.C# .Net Parsing XML Strings

Lo que tengo es ...

<whmcsapi version="4.1.2"> 
<action>getstaffonline</action> 
<result>success</result> 
<totalresults>1</totalresults> 
<staffonline> 
    <staff> 
    <adminusername>Admin</adminusername> 
    <logintime>2010-03-03 18:29:12</logintime> 
    <ipaddress>127.0.0.1</ipaddress> 
    <lastvisit>2010-03-03 18:30:43</lastvisit> 
    </staff> 
</staffonline> 
</whmcsapi> 

que sólo necesita para obtener los valores para y la información de cada miembro del personal (incluido en las etiquetas). ¿Alguien puede decirme cuál sería la mejor manera de hacer esto y posiblemente un pequeño ejemplo?

Gracias!

+0

Sugerencia: Su nodo raíz se llama 'whmcsapi' –

+1

posible duplicado de [¿Cómo puedo leer y analizar un archivo XML en C#?] (Http://stackoverflow.com/questions/642293/how-do- i-read-and-parse-an-xml-file-in-c) –

+2

El problema es que no estoy analizando un archivo, tengo los datos XML en una cadena. Todo lo que encuentro es sobre cómo analizar un archivo. –

Respuesta

12
var staff = XDocument.Parse(myXml) 
    .Descendants("staff") 
    .Select(n => new { 
         adminusername = n.Element("adminusername").Value, 
         ... 
        }); 
3

más comúnmente utilizada es Linq to XML estos días, se integra análisis XML en LINQ para un agradable, sucinta y expresiva sintaxis:

XDocument xmlDoc = XDocument.Load(@"testData.xml"); 
var staffMembers = xmlDoc.Descendants("staff") 
         .Select(staff => new { Name = staff.Element("adminusername").Value, 
               LoginTime = staff.Element("logintime").Value, 
               IpAddress = staff.Element("ipaddress").Value, 
               LastVisit = staff.Element("lastvisit").Value, 
              }).ToList(); 
+0

No entiendo por qué esto está teniendo problemas. No importa cómo lo intente, obtengo "caracteres ilegales en el camino". ¿No puedo cargarlo así desde una cadena? http://www.ampaste.net/m3651f133 –

+1

para cargar desde una cadena usa 'XDocument.Parse (myString)' – BrokenGlass

+0

Ah, gracias, acabo de notarlo por el otro comentario. ¿Ves por qué esto no funcionaría? Las dos partes en la parte inferior del método no actualizan el listbox y la etiqueta, aunque el XML se está extrayendo correctamente. Entonces supongo que es un problema de análisis. http://www.ampaste.net/m61f246e1 –

0
XDocument doc = XDocument.Load("staff.xml"); 

var query = from r in doc.Descendants("staff") 
      select new 
        { 
         Adminusername = r.Element("adminusername").Value, 
         LoginTime = r.Element("logintime").Value, 
         IpAddress = r.Element("ipaddress").Value, 
         LastVisit = r.Element("lastvisit").Value 
        }; 
-3

Aquí es una función que yo uso que funciona perfectamente para analizar archivos xml He incluido una clase 'delimitador' que se puede utilizar para almacenar los delimitadores XML como

<startTag></endTag> 

Muy fácil de usar, y funciona como un encanto ... hágamelo saber si usted tiene alguna pregunta

utilice la función como esta:

XmlDataManager.List<XmlManager.Delimeter> delimeters = new List<XmlManager.Delimeter>("<result>","</result>"); 
int[] splitIndexArray = { 1 }; // Tells the function where to split in case where the same value occurs multiple times in a line... usually 1 need an entry for each value 
String testValue = ""; 
List<String> values = new List<String> {testValue} 
XmlDataManager.ReadValues(delimeters, values, `<xmlFileNameHere>,` splitIndexArray); 

Aquí es la clase:

public class XmlDataManager 
{ 
    const String XML_FILE_WRITE_FAIL = "Could not write to xml file"; 
    const String XML_FILE_READ_FAIL = "Could not read from xml file"; 
    const String XML_FILE_WRITE_BUILDER_FAIL = "Could not write values to string"; 


    /// <summary> 
    /// 
    /// </summary> 
    public struct Delimeter 
    { 
     internal String StartDelimeter { get { return _startDelimeter; } } 
     internal String EndDelimeter { get { return _endDelimeter; } } 
     private readonly String _startDelimeter; 
     private readonly String _endDelimeter; 

     public Delimeter(String startDelimeter, String endDelimeter) 
     { 
      _startDelimeter = startDelimeter; 
      _endDelimeter = endDelimeter; 
     } 

     public Delimeter(String startDelimeter) 
     { 
      _startDelimeter = startDelimeter; 
      _endDelimeter = String.Empty; 
     } 
    } 


    public static void ReadValuesLineByLine( List<Delimeter> elementDelimeters, 
               List<String> values, 
               String fileName, 
               int[] splitIndexes) 
    { 
     try 
     { 
      using (StreamReader sr = new StreamReader(fileName)) 
      { 
       String line = sr.ReadLine(); 
       while (!sr.EndOfStream) 
       { 
        for (int i = 0; i <= values.Count-1; i++) 
        { 
         if (line.Contains(elementDelimeters[i].StartDelimeter)) 
         { 
          String[] delimeters = { elementDelimeters[i].StartDelimeter, elementDelimeters[i].EndDelimeter }; 
          String[] elements = line.Split(delimeters, StringSplitOptions.None); 
          values[i] = elements[splitIndexes[i]]; 
         } 
        } 
        line = sr.ReadLine(); 
       } 
      } 
     } 
     catch(Exception ex) 
     { 
      throw new Exception(XML_FILE_READ_FAIL, ex); 
     } 
    } 
} 

Peter

+1

¿Existe alguna razón por la que hayas inventado tu propia clase de análisis XML cuando hay una funcionalidad totalmente lista para hacer eso? Estoy un poco sorprendido, tengo que decir. – BrokenGlass

+0

En serio, ¿por qué te harías eso? – Jordan