2009-11-10 11 views
7

Non è necessario modificare alcun file XML o altro, questo è solo per la lettura e l'analisi.Conversione di un documento XML in un dizionario

Desidero essere in grado di gestire il documento XML come un dizionario, ad esempio: username = doc["username"];, ma non riesco a trovare il modo di "convertire" il documento. Ho anche riscontrato il problema con nomi di chiavi duplicati, ma questo potrebbe essere evitato facilmente aggiungendo ogni valore con 1, 2 ecc; rendendo facile anche il ciclo continuo.

È possibile? Per trattare il documento XML (analizzato) come un dizionario?


Risposta a Mehrdad: Esso varia di volta in volta, dipende dalla richiesta da parte dell'utente. Se l'utente richiede x, allora sarà:

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

Ma qualora chieda y, sarà come

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

La cosa migliore sarebbe se questo:

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

Potrebbe essere analizzato e quindi accessibile come doc["mengde"] ecc.

+0

Qual è la struttura del documento XML? –

+0

Come si desidera gestire i documenti secondari? Che cosa significa DOC Ritorna [ "foo"] in ''? Devi spiegare come vuoi accedere a doc/foo/a affinché noi possiamo aiutarti. – jmucchiello

+0

I nodi che contengono nodi verranno ingnorizzati, io uso solo quelli contenenti testo. Nel tuo esempio: x, a e b. – Phoexo

risposta

12

Si potrebbe usare LINQ to xml a fare quello che vuoi (se ho capito quello che vuoi)

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

Grazie! Lavorato esattamente come escluso :) – Phoexo

4

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

codice di conversione

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

Questa domanda è stato chiesto prima qui e quindi si possono trovare le tutte le risposte a questo link:

convert xml to sorted dictionary

Spero che aiuti.

+0

Ty, ma preferirei usare il nome del tag piuttosto che aggiungere un attributo a tutto. – Phoexo

0

Ci deve essere un modo più facile di questo pasticcio? Anche questo è a pagamento in quanto sarò in grado di rilevare bambini di bambini.

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

Guarda in ricorsione. – jmucchiello

4

La tua domanda non è davvero molto chiaro, ma penso che questo fa ciò che si vuole:

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; 
} 
Problemi correlati