2009-11-10 42 views
7

No necesito editar ningún archivo XML ni nada, esto es solo para leer y analizar.Convirtiendo un documento XML a un diccionario

Quiero ser capaz de manejar el documento XML como un diccionario, como: username = doc["username"];, pero no puedo encontrar la manera de "convertir" el documento. También he encontrado el problema con los nombres de clave duplicados, pero eso podría evitarse fácilmente al agregar cada valor con 1, 2, etc. haciendo que sea fácil de pasar también.

¿Esto es posible? ¿Para tratar el documento XML (analizado) como un diccionario?


respuesta a Mehrdad: Esto varía de vez en cuando, que depende de la solicitud del usuario. Si el usuario solicita x, entonces será:

<xml> 
    <test>foo</test> 
    <bar>123</bar> 
    <username>foobar</username> 
</xml> 

Pero si solicita y, será como

<xml> 
    <ammount>1000</ammount> 
    <mail>[email protected]</mail> 
    <username>foobar</username> 
</xml> 

Lo mejor sería si esto:

<xml> 
<mengde>100</mengde> 
<type>3</type> 
<mail>foo</mail> 
<crypt>bar</crypt> 
<username>bar</username> 
</xml>" 

Se pudo analizar y luego se accedió como doc["mengde"] etc.

+0

¿Cuál es la estructura del documento XML? –

+0

¿Cómo quieres manejar los subdocumentos? Lo que hace doc [ "foo"] retorno en ''? Debe explicar cómo desea acceder a doc/foo/a para ayudarnos. – jmucchiello

+0

Se estudiarán los nodos que contienen nodos, solo uso los que contienen texto. En tu ejemplo: x, a y b. – Phoexo

Respuesta

12

Usted podría utilizar LINQ to XML para hacer lo que quiere (si entiendo lo que quiere)

string data = "<data><test>foo</test><test>foobbbbb</test><bar>123</bar><username>foobar</username></data>"; 

XDocument doc = XDocument.Parse(data); 
Dictionary<string, string> dataDictionary = new Dictionary<string, string>(); 

foreach (XElement element in doc.Descendants().Where(p => p.HasElements == false)) { 
    int keyInt = 0; 
    string keyName = element.Name.LocalName; 

    while (dataDictionary.ContainsKey(keyName)) { 
     keyName = element.Name.LocalName + "_" + keyInt++; 
    } 

    dataDictionary.Add(keyName, element.Value); 
} 
+0

¡Gracias! Trabajado excactly como exceptuado :) – Phoexo

4

datos XML

<?xml version="1.0" encoding="UTF-8"?> 
<data> 
    <resource key="123">foo</resource> 
    <resource key="456">bar</resource> 
    <resource key="789">bar</resource> 
</data> 

Código Conversión

string s = "<data><resource key=\"123\">foo</resource><resource key=\"456\">bar</resource><resource key=\"789\">bar</resource></data>"; 
XmlDocument xml = new XmlDocument(); 
xml.LoadXml(s); 
XmlNodeList resources = xml.SelectNodes("data/resource"); 
SortedDictionary<string,string> dictionary = new SortedDictionary<string,string>(); 
foreach (XmlNode node in resources){ 
    dictionary.Add(node.Attributes["key"].Value, node.InnerText); 
} 

Esta pregunta fue hecha antes de que aquí y para que pueda encontrar las todas las respuestas en este enlace:

convert xml to sorted dictionary

Espero que ayude.

+0

Ty, pero prefiero poder usar el nombre de etiqueta que agregar un atributo a todo. – Phoexo

0

Tiene que haber una manera más fácil que este lío? Esto también es libido ya que solo podría detectar hijos de niños.

string s = @" 
<xml> 
<mengde>100</mengde> 
<type>2</type> 
<foo>bar</foo> 
</xml>"; 

XmlDocument xml = new XmlDocument(); 
xml.LoadXml(s); 
SortedDictionary<string, string> dictionary = new SortedDictionary<string, string>(); 
foreach (XmlNode node in xml) 
{ 
    if (node.NodeType == XmlNodeType.Element && node.HasChildNodes) 
    { 
     foreach (XmlNode node2 in node) 
     { 
      if (node2.NodeType == XmlNodeType.Element && node2.HasChildNodes) 
      { 
       foreach (XmlNode node3 in node2) 
       { 
        if (node3.NodeType == XmlNodeType.Element && node3.HasChildNodes) 
        { 
         foreach (XmlNode node4 in node3) 
         { 
          if (node4.NodeType == XmlNodeType.Element && node4.HasChildNodes) 
          { 
           foreach (XmlNode node5 in node4) 
           { 
            dictionary.Add(node5.ParentNode.Name, node5.InnerText); 
           } 
          } 
          else 
          { 
           dictionary.Add(node4.ParentNode.Name, node4.InnerText); 
          } 
         } 
        } 
        else 
        { 
         dictionary.Add(node3.ParentNode.Name, node3.InnerText); 
        } 
       } 
      } 
      else 
      { 
       dictionary.Add(node2.Name, node2.InnerText); 
      } 
     } 
    } 
    else 
    { 
     dictionary.Add(node.Name, node.InnerText); 
    } 
} 
+3

Mire en recursividad. – jmucchiello

4

Su pregunta no es realmente muy claro, pero creo que esto hace lo que quiere:

XmlDocument doc = new XmlDocument(); 
doc.LoadXml(@"<xml> 
<mengde>100</mengde> 
<type>2</type> 
<foo>bar</foo> 
</xml>"); 

Dictionary<string, string> d = new Dictionary<string, string>(); 
foreach (XmlNode n in doc.SelectNodes("/xml/*") 
{ 
    d[n.Name] = n.Value; 
} 
Cuestiones relacionadas