2009-11-10 16 views
7

Nie trzeba edytować żadnego pliku XML ani niczego, jest to tylko do odczytu i parsowania.Konwersja dokumentu XML do słownika

Chcę móc obsługiwać dokument XML jako słownik, na przykład: username = doc["username"];, ale nie mogę się dowiedzieć, jak "przekonwertować" dokument. Napotkałem również problem z duplikatami nazw kluczy, ale można tego łatwo uniknąć, dołączając każdą wartość za pomocą 1, 2 itd; ułatwienie przeplatania się.

Czy to możliwe? Traktować (parsowany) dokument XML jako słownik?


Odpowiedź na Mehrdad: różni się on od czasu do czasu, to zależy na żądanie użytkownika. Jeżeli użytkownik żąda x, to będzie:

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

Ale jeśli zażąda y, to będzie jak

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

Najlepiej byłoby, gdyby to:

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

Może zostać przeanalizowany, a następnie udostępniony jako doc["mengde"] itd.

+0

Jaka jest struktura dokumentu XML? –

+0

Jak radzić sobie z dokumentami cząstkowymi? Co doc [ "foo"] powrót w ''? Musisz wyjaśnić, w jaki sposób chcesz uzyskać dostęp do dokumentu doc ​​/ foo/a, abyśmy mogli Ci pomóc. – jmucchiello

+0

Węzły zawierające węzły będą zapisywane, używam tylko tych, które zawierają tekst. W twoim przykładzie: x, a i b. – Phoexo

Odpowiedz

12

Można użyć LINQ do XML robić to, co chcesz (jeśli dobrze rozumiem, co chcesz)

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

Dziękujemy! Pracował dokładnie tak, jak z wyjątkiem :) – Phoexo

4

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

kod konwersji

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

To pytanie było zadawane zanim tu i tak można znaleźć wszystkie odpowiedzi w tym linku:

convert xml to sorted dictionary

Mam nadzieję, że to pomaga.

+0

Ty, ale wolałbym używać nazwy znacznika niż dodawać atrybut do wszystkiego. – Phoexo

0

Musi być łatwiejszy sposób niż ten bałagan? Jest to również ograniczone, ponieważ będę w stanie wykryć dzieci dzieci.

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

Sprawdź rekursję. – jmucchiello

4

Twoje pytanie naprawdę nie jest bardzo jasne, ale myślę, że robi to, co chcesz:

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