views:

318

answers:

5

I do not need to edit any XML-file or anything, this is only for reading and parsing.

I want to be able to handle the XML-document as a dictionary, like: username = doc["username"];, but I can't find out how to "convert" the document. I've also encountered the problem with duplicate key-names, but that could be easlily avoided by appending each value with 1, 2 etc; making it easy to for-loop through too.

Is this possible? To treat the (parsed) XML-document as a dictionary?


Answer to Mehrdad: It varies from time to time, it depends on the request from the user. If the user requests x, then it will be:

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

But if he requests y, it will be like

<xml>
    <ammount>1000</ammount>
    <mail>...@...</mail>
    <username>foobar</username>
</xml>


The best would be if this:

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

Could be parsed and then accessed as doc["mengde"] etc.

+1  A: 

XML Data

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

Conversion Code

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

This question was asked before here and so you can find the all answers in this link :

http://stackoverflow.com/questions/653540/convert-xml-to-sorted-dictionary

Hope it helps.

Braveyard
Ty, but I'd rather be able to use the tag-name than to add an attribute to everything.
Phoexo
A: 

This isn't exactly what you are looking for, but may be of interest: http://blogs.msdn.com/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introducing-the-expandoobject.aspx

nikmd23
That's for C# 4.0 and about the use of ExpandoObject and dynamic, so it doesn't help me.
Phoexo
Ah, sorry about that.
nikmd23
A: 

There's gotta be a easier way than this mess? This is also libited as i only would be able to detect children of children.

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);
    }
}
Phoexo
Look into recursion.
jmucchiello
+2  A: 

You could use linq to xml to do what you want (if I understand what you want)

        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);
        }
mdm20
Thank you! Worked excactly as excepted :)
Phoexo
A: 

Your question's really not very clear, but I think this does what you want:

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