views:

357

answers:

8

I have the following set of data

<ids>
   <id1 attr1="value1" attr2="value2" />
   <id2 attr3="value3" attr4="value4" />
   <id3 attr2="value6" attr5="value7" />
</ids>

Basically, it's an XML that can have any node name with any attribute name with any attribute value.

After parsing the XML, I store the attribute data in a Dictionary. Then I store that same Dictionary as a value with the node name as a key. So my data structure would be a Dictionary<string, Dictionary<string, string>> (let's give this a variable name called "dict") So if I wanted to get the value for attr2 in the id1 node, I would do:

string value = dict["id1"]["attr2"];
// value will be value2

I think this is a pretty simple and workable solution for my needs, but there just seems to be this voice at the back of my head telling me that there is a different data structure or simpler solution that I'm missing out on. What does everyone think?

+1  A: 

As long as all of the nodes have unique names, you should be OK. Note that it won't really work for XML like this:

<nodes>
     <node id="id1" attr1="value1" attr2="value2" />
     <node id="id2" attr3="value3" attr4="value4" />
     <node id="id3" attr2="value6" attr5="value7" />
</nodes>
Yuliy
In that case you'd be better off with a List<Dictionary<string, string>> since you don't have uniqueness across your node names.
Joseph
A: 

Given that the XML can have any node name and any attribute name I think your current solution is optimal.

Andrew Hare
+2  A: 

That XML doesn't look very good. It's not semantic XML at all. Semantic XML would be:

<data>
    <item id="id1">
        <value name="attr1">value1</value>
        <!-- ... -->
    </item>
    <!-- ... -->
</data>

I know it's bigger, but that's XML for you. The reason I'm even saying this is that if you're not ready to go with semantic XML, you're probably looking for another data format. XML is a little bit bloated by nature. If you're looking for a compact format, have a look at JSON.

Anyways, using semantic XML, I would recommend XPath. Have a look in the MSDN documentation and look at the SelectNodes methods in the DOM objects.

Short example:

XmlDocument doc = new XmlDocument();
doc.Load("data.xml");

// Get a single item.
XmlNode item = doc.SelectSingleNode("//item[@id=myid]");
Blixt
You make a good point on semantic XML. Looking back at my XML sample, it does lack semantic information that other people might not be able to identify with. I'll look into improving it.
Klaw
A: 

Why not to use something that already exists? Like Simple XML Parser in C#

z-boss
+4  A: 

I think your solution is a good one. It will provide very fast lookups, and matches exactly to your domain.

Is your main problem with the nested dictionaries? If so, I would suggest that you not worry about it - using collections of collections is often a very useful tool.

My only complaint would be this: If you're not using this frequently, you're going to be loading a lot of information into a data structure that may be unncessary. If this is for one time lookups, leaving it in XML and using XPath queries may be a more optimal solution than pre-parsing and loading the entire thing into memory. If you're querying this frequently, though, this is a more optimal solution.

Reed Copsey
You are exactly right about my worries on nested dictionaries. :) The data will be retrieved quite frequently, that's why I decided to load it all at once for optimization purposes (as opposed to parsing the XML every so often), and the memory footprint will be small because the number of nodes is going to be probably less than 10.But you make a good point on leaving it in XML on one-time lookups.
Klaw
Nested dictionaries are very useful - I've used them many times, and don't feel they are anything to avoid. I'd say just stick with your current architecture.
Reed Copsey
+2  A: 

Just for grins - what if you kept the XML DOM and found your attributes with XPath queries? That way if you had duplicate node names you could accomodate that.

n8wrl
+1 for not re-inventing the wheel
Orion Adrian
This would be _much_ slower than a Dictionary.
Andrew Hare
And probably be more expensive in terms of memory.
Dolphin
A: 

If you need an XML grammar then create one for your needs. If you need a parser then use one of the many excellent ones provided in the .Net library. If you need to store the document in memory and access it use the DOM and XPath to select nodes. If you don't need any of this, then I would recommend against using XML and instead using something simpler like JSON.

If you need to keep the whole thing in memory, but just the values, then I suggest using the DataSets and loading them with the the XML loaders.

Orion Adrian
+2  A: 

How about a class?

public class YourId
{
    public string Id { get; set; }
    public string Attribute1 { get; set; }
    public string Value { get; set; }
}

Then you could create a List and populate it via your xml... It would be easy to work with and you could use linq with it:

List<YourId> items = GetIdsFromXml();

var query = from i in items
            where i.Id == "id1"
            select i;

// or...

items.Where(i => i.Attribute == "blah").ToList();

// ect.
J.13.L