Sunday, 15 June 2014

c# - What is the best way to store and play back XML nodes? -



c# - What is the best way to store and play back XML nodes? -

i have xml looks (highly simplified):

<?xml version="1.0"?> <example> <shortcuts> <shortcut name="shortcut1"> <property name="name1" value="value1" /> <property name="name2" value="value2" /> </shortcut> </shortcuts> <data> <datum name="datum1"> <property name="name1" value="value1" /> <property name="name2" value="value2" /> </datum> <datum name="datum2"> <shortcutref name="shortcut1" /> </datum> <datum name="datum3"> <shortcutref name="shortcut1" /> <property name="name3" value="value3" /> </datum> </data> </example>

as can see, structured such "shortcuts" can defined consist of 1 or more properties. info can described explicitly properties, or 1 or more shortcuts, or mix of both (and there no specific order).

i want parse xmlreader (xmldocument easier won't work here because xml file large). thought way store xml subtrees of each shortcut in dictionary keyed shortcut names, unique. when referenced, read through subtree xmlreader rather main one. subtree xmlreader must still linked main xmlreader because xml comes out not expect. here code:

using(xmlreader xml = xmlreader.create("example.xml")) { dictionary<string, xmlreader> shortcuts = new dictionary<string, xmlreader>(); xml.readtodescendant("shortcuts"); xml.readtodescendant("shortcut"); { shortcuts.add(xml.getattribute("name"), xml.readsubtree()); } while(xml.readtonextsibling("shortcut")); xml.readtofollowing("data"); while(xml.readtofollowing("datum")) { console.writeline(xml.getattribute("name")); xmlreader datum = xml.readsubtree(); while(datum.read()) { if(datum.name == "property") { console.writeline(datum.getattribute("name") + ':' + datum.getattribute("value")); } else if(datum.name == "shortcutref") { xmlreader shortcut_ref = shortcuts[datum.getattribute("name")]; while(shortcut_ref.readtofollowing("property")) { console.writeline(shortcut_ref.getattribute("name") + ':' + shortcut_ref.getattribute("value")); } } } } }

what best way parse xml structured in way?

it’s not exclusively clear want – since utilize words “play back” guessing don’t need store values xml nodes (data / datum) in memory (you can discard them after use), need cache shortcut properties can re-iterate through them when referenced… had it, instead of storing xml nodes, store objects instead in dictionary.

public class property { public string name { get; set; } public string value { get; set; } } public class shortcut { public list<property> properties = new list<property>(); } class programme { static void main(string[] args) { filestream fs = new filestream(@"c:\temp\example.xml", filemode.open, fileaccess.read); xmltextreader reader = new xmltextreader(fs); dictionary<string, shortcut> shortcutdictionary = new dictionary<string, shortcut>(); while (reader.read()) { if (reader.nodetype == xmlnodetype.element && reader.localname == "shortcuts") { while (reader.read()) { if (reader.nodetype == xmlnodetype.element && reader.localname == "shortcut") { shortcut shortcut = new shortcut(); shortcutdictionary.add(reader.getattribute("name"), shortcut); while (reader.read()) { if (reader.nodetype == xmlnodetype.element && reader.localname == "property") shortcut.properties.add(new property() { name = reader.getattribute("name"), value = reader.getattribute("value") }); else if (reader.nodetype == xmlnodetype.endelement && reader.localname == "shortcut") break; } } else if (reader.nodetype == xmlnodetype.endelement && reader.localname == "shortcuts") break; } } if (reader.nodetype == xmlnodetype.element && reader.localname == "data") { while (reader.read()) { if (reader.nodetype == xmlnodetype.element && reader.localname == "datum") { while (reader.read()) { if (reader.nodetype == xmlnodetype.element && reader.localname == "property") { console.writeline(reader.getattribute("name") + ':' + reader.getattribute("value")); } else if (reader.nodetype == xmlnodetype.element && reader.localname == "shortcutref") { foreach (property property in shortcutdictionary[reader.getattribute("name")].properties) console.writeline(property.name + ':' + property.value); } else if (reader.nodetype == xmlnodetype.endelement && reader.localname == "datum") break; } } else if (reader.nodetype == xmlnodetype.endelement && reader.localname == "data") break; } } } reader.close(); fs.close(); } }

otherwise, if not it, trying access serial info in random access manner. best bet convert/save info database. sqlite it.

c# .net xml memory-management xmlreader

No comments:

Post a Comment