我需要在正确的方向上推动如何将整个XML文档解析为字典。我的计划是将密钥作为路径,每个嵌套类型由“ - >”分隔。例如:
<Foo>
<Bar>3</Bar>
<Foo>
<Bar>10</Bar>
</Foo>
</Foo>
如果我想获得一个值,我只需使用以下方法将其从字典中删除:
string value = Elements["Foo->Bar"];
我不确定如何递归地浏览每个元素。 任何帮助表示赞赏。
答案 0 :(得分:4)
直截了当的解决方案:
private static string GetElementPath(XElement element)
{
var parent = element.Parent;
if(parent == null)
{
return element.Name.LocalName;
}
else
{
return GetElementPath(parent) + "->" + element.Name.LocalName;
}
}
static void Main(string[] args)
{
var xml = @"
<Foo>
<Bar>3</Bar>
<Foo>
<Bar>10</Bar>
</Foo>
</Foo>";
var xdoc = XDocument.Parse(xml);
var dictionary = new Dictionary<string, string>();
foreach(var element in xdoc.Descendants())
{
if(!element.HasElements)
{
var key = GetElementPath(element);
dictionary[key] = (string)element;
}
}
Console.WriteLine(dictionary["Foo->Bar"]);
}
答案 1 :(得分:0)
你需要看看xpath,所用路径的格式与你想要的路径有点不同,但是你可以创建一个包裹函数,如果是nessacary
string GetByPath(string mypath)
{
//process path, and reformat it to xpath
//then get by xpath
}
http://support.microsoft.com/kb/308333
http://www.codeproject.com/Articles/9494/Manipulate-XML-data-with-XPath-and-XmlDocument-C
答案 2 :(得分:0)
另一种选择,但不确定XML文档的真实结构
string data = "<Foo><Bar>3</Bar><Foo><bar>123</bar></Foo></Foo>";
XDocument xdoc = XDocument.Parse(data);
Dictionary<string, string> dataDict = new Dictionary<string, string>();
foreach (XElement xelement in doc.Descendants().Where(x => x.HasElements == false))
{
int keyInt = 0;
string keyName = xelement.Name.LocalName;
while (dataDict.ContainsKey(keyName))
keyName = xelement.Name.LocalName + "->" + keyInt++;
dataDict.Add(keyName, xelement.Value);
}
答案 3 :(得分:0)
public static void parse()
{
Stack<String> stck = new Stack<string>();
List<String> nodes = new List<string>();
Dictionary<String, String> dictionary = new Dictionary<string, string>();
using (XmlReader reader = XmlReader.Create("path:\\xml.xml"))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
stck.Push(reader.Name);
}
if (reader.NodeType == XmlNodeType.Text)
{
StringBuilder str = new StringBuilder();
if (stck.Count > 0)
nodes = stck.ToList<String>();
//List<String> _nodes ;
nodes.Reverse(0,nodes.Count);
foreach (String node in nodes)
str.Append(node + " --> ");
dictionary.Add(str.ToString(), reader.Value);
str.Clear();
}
if (reader.NodeType == XmlNodeType.EndElement)
{
stck.Pop();
}
}
}
foreach (KeyValuePair<String, String> KVPair in dictionary)
Console.WriteLine(KVPair.Key + " : " + KVPair.Value);
Console.Read();
}