1

XML データを辞書に変換しようとしています。同一のノード名に問題があります。C# .ネット 3.5

サンプル XML = 問題は、これを制御できないことです。処理するしかない。

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <a1>val1</a1>
  <a2>val2</a2>
  <Parameter>
    <ParameterName>param1</ParameterName>
    <ParameterValue>paramval1</ParameterValue>
  </Parameter>
  <Parameter>
    <ParameterName>param2</ParameterName>
    <ParameterValue>paramval2</ParameterValue>
  </Parameter>
</Root>

私の試み:

XMLStream.Position = 0;
        XElement xmlDetails2 = XElement.Load(new System.IO.StreamReader(XMLStream));
        var x = xmlDetails2.Elements().ToDictionary(
            e => e.Name.LocalName,
            e => e.Elements()
                      .ToDictionary(
                          f => f.Name.LocalName,
                          f => f.Value));

私が得ているエラー(もちろん理にかなっています):

An item with the same key has already been added.

期待される結果 (xml の例から):

a1 => val1
a2 => val2
param1 => paramval1
param2 => paramval2
...

@LB の提案に基づいて独自に作成しました。それは最善の解決策ではありませんが、今のところうまくいきます。

public void XMLTODictionary(XElement xmlDetails, ref Dictionary<string, string> dic)
{
    foreach (var node in xmlDetails.Elements())
    {
        if (node.Name.LocalName.Equals("parameter", StringComparison.CurrentCultureIgnoreCase))
        {
                dic.Add(node.Element("ParameterName").Value, node.Element("ParameterValue").Value);
        }
        else
        {
            dic.Add(node.Name.LocalName, node.Value);
        }
    }
}
4

4 に答える 4

0

これを作ったばかりで、私のために働きます。少しぎこちない。テンプレートとして使用します。

        public static Dictionary<string, dynamic> RecDis(string ThisXML)
    {
        Dictionary<string, dynamic> ThisBlock = new Dictionary<string, dynamic>();

        XElement doc = XElement.Parse(ThisXML);

        XNode[] ThisNoideArray = doc.Nodes().ToArray();

        foreach (XNode park in ThisNoideArray)
        {
            XElement parker = XElement.Parse(park.ToString());

            if (parker.HasElements)
            {
                ThisBlock.Add(parker.Name.ToString(), RecDis(parker.ToString()));
            }
            else
            {
                ThisBlock.Add(parker.Name.ToString(), parker.Value.ToString());
            }
        }

        return ThisBlock;
    }
于 2016-04-04T13:41:13.280 に答える
0

一意の null 非許容キーを提供しない限り、辞書構造にインポートすることはできません。私が考えることができるいくつかのオプション:

  • インポート中に人工キーを作成する
  • 代わりに ToLookup() 拡張メソッドを利用してください。これは辞書を返しませんが、ニーズに合うかもしれません。辞書が必要な理由をよりよく理解できれば、さらにお役に立てるかもしれません。
于 2012-12-06T19:53:44.630 に答える
0

これは、データをタプルに抽出して辞書を出力するメソッドです。重複キーはチェックされませんが、追加できることに注意してください。

string data = @"<?xml version=""1.0"" encoding=""utf-8""?>
<Root>
  <a1>val1</a1>
  <a2>val2</a2>
  <Parameter>
    <ParameterName>param1</ParameterName>
    <ParameterValue>paramval1</ParameterValue>
  </Parameter>
  <Parameter>
    <ParameterName>param2</ParameterName>
    <ParameterValue>paramval2</ParameterValue>
  </Parameter>
</Root>";

var elements = XDocument.Parse( data )
                        .Element("Root")
                        .Descendants();

var asTupleChildren =  elements.Where (e => e.HasElements)
                               .Select (e => new Tuple<string,string>(e.Element("ParameterName").Value, e.Element("ParameterValue").Value ));

var asTupleElements =  elements.Where (e => e.HasElements == false)
                               .Where (e => e.Name != "ParameterName" && e.Name != "ParameterValue" )
                               .Select (e => new Tuple<string,string>(e.Name.ToString(), e.Value ));


var asDictionary =  asTupleElements.Concat(asTupleChildren)
                                   .ToDictionary (te => te.Item1, te => te.Item2);


/* asDictionary is a Dictionary<String,String> (4 items)

a1 val1
a2 val2
param1 paramval1
param2 paramval2

*/
于 2012-12-06T20:51:21.897 に答える
0

ここでDynamicXmlを使用するのはどうですか

dynamic root = DynamicXml.Load("a.xml");

Console.WriteLine(root.a1);
foreach (var p in root.Parameter)
{
    Console.WriteLine("{0}:{1}",p.ParameterName, p.ParameterValue);
}
Console.WriteLine(root.Parameter[0].ParameterValue);

編集

一般的なアプローチは、ディクショナリを取得することですがDictionary<string,object> 、xml をディクショナリに変換する際にいくつかの問題があります。例えば

<a1>val1</a1>

dict["a1"]val1を返しますが、この xml は何を返しますか

<a1 name="valAttr"><name>valName</name><a1>

dict["a1"]["name"]? valAttrまたはvalName ?

あなたの例を考えると、 と の唯一の違いdict["a1"]dict["Parameter"]Parameterが同じ親の下に複数存在し、単一の要素ではなく配列と見なされることです。

DynamicXmlは、これらの問題を解決しようとします。もちろん、改善の余地はたくさんありますが、基本的なニーズには十分対応できるはずです。

于 2012-12-06T20:01:06.750 に答える