如何在C#中将XML片段转换为Dictionary?

时间:2017-02-07 13:16:14

标签: c# asp.net fix-protocol

我有方法XmlToDictionary的以下代码。但是如何从一个按钮给出输入,以便将XML数据转换为Dictionary

XML输入

<messageTags>
  <tag key="35" value="U1" />
  <tag key="49" value="GEMI1" />
  <tag key="8" value="FIX.4.1" />
  <tag key="9" value="732" />
<messageTags/>

我希望输出如下

35=U149=GEMI18=FIX.4.19=732

XmlToDictionary的代码()

public static Dictionary<string, string> XmlToDictionary(string key, string value, XElement baseElm)
{
    Dictionary<string, string> dict = new Dictionary<string, string>();

    foreach (XElement elm in baseElm.Elements())
    {
        string dictKey = elm.Attribute(key).Value;
        string dictVal = elm.Attribute(value).Value;
        dict.Add(dictKey, dictVal);
    }

    return dict;
}

按钮点击代码()

private void button2_Click(object sender, EventArgs e)
{
    XElement xs = new XElement("messageTags", "tag");
    XmlToDictionary("23", "EUI", xs);
    richTextBox4.Text = XmlToDictionary("messageTags","tag",xs).ToString();                       
}

3 个答案:

答案 0 :(得分:1)

试试这个......

以下代码将为您提供一个包含XML所有值的字典对象

 private static void ReadXML2()
    {
        string sXML = "<messageTags>"+
                      "<tag key=\"35\" value=\"U1\" />"+
                      "<tag key=\"49\" value=\"GEMI1\" />"+
                      "<tag key=\"8\" value=\"FIX.4.1\" />"+
                      "<tag key=\"9\" value=\"732\" />"+
                    "</messageTags>";

        XDocument doc = XDocument.Parse(sXML);
        var v = (from p in doc.Descendants("tag")
                 select p).ToDictionary(item => item.Attribute("key").Value,item=> item.Attribute("value").Value);
        Console.WriteLine(v.Count());

    }

创建字典对象后,您可以使用您的方法查找特定的键/值..

顺便说一下你的XML字符串是错误的。您没有messagetags的结束标记

<强>更新 使用以下不需要Dictionary对象的代码

 var v2 = (from p in doc.Descendants("tag")
                 select p);

        string sOutput = "";
        foreach (var item in v2)
        {
            sOutput += item.Attribute("key").Value + "=" + item.Attribute("value").Value;
        }

        Console.WriteLine(sOutput);

输出

35 = U149 = GEMI18 = FIX.4.19 = 732

答案 1 :(得分:1)

您的真正的问题是您要生成FIX消息。您试图通过生成字典(为什么?)然后在其上调用ToString()来执行此操作。这不起作用,因为ToString()的默认实现是键入对象的名称。

您根本不需要浏览字典,只需解析XML片段并从标记生成最终字符串。快速而肮脏的尝试:

string fragment = "<messageTags>" +
                "<tag key=\"35\" value=\"U1\" />" +
                "<tag key=\"49\" value=\"GEMI1\" />" +
                "<tag key=\"8\" value=\"FIX.4.1\" />" +
                "<tag key=\"9\" value=\"732\" />" +
            "</messageTags>";

var doc = XDocument.Parse(fragment);
var tags = from tag in doc.Descendants("tag")
           select String.Format("{0}={1}",
                                tag.Attribute("key").Value, 
                                tag.Attribute("value").Value);
var message = String.Join("",tags);
Console.WriteLine(message);

将返回35=U149=GEMI18=FIX.4.19=732

此尝试很脏,因为它会生成临时字符串,每个标记对对应一个字符串。 FIX用于高吞吐量环境,这意味着性能很重要

更好的方法是使用StringBuilder和循环:

var doc = XDocument.Parse(fragment);    
var builder = new StringBuilder();
foreach(var tag in doc.Descendants("tag"))
{
    builder.AppendFormat("{0}={1}", 
                         tag.Attribute("key").Value, 
                         tag.Attribute("value").Value);
};
var message = builder.ToString();

答案 2 :(得分:0)

请参阅下面的我的版本。将其保留为可调用的方法。

<强>已更新

按你的意愿做了但是......我认为你的请求中有错误......仔细看看&#39; 35 = U149 = GEMI18 = FIX.4.19 = 732&#39;如何消耗这个gona知道GEMI18是GEMI1 [空间] 8

  public static void DoStuff()
    {
        var stringXml = @"<messageTags> 
                                <tag key=""35"" value=""U1"" />
                                <tag key=""49"" value=""GEMI1"" />
                                <tag key=""8"" value=""FIX.4.1"" />
                                <tag key=""9"" value=""732"" />
                       </messageTags>";

        XmlDocument xmltest = new XmlDocument();
        xmltest.LoadXml(stringXml);

        XmlNodeList elemlist = xmltest.GetElementsByTagName("messageTags");

        var dic = XmlNodeListToDictionaryByAttribute("key", "value", elemlist);
        var test = DictToString(dic, "{0}={1}");
    }

    public static Dictionary<string, string> XmlNodeListToDictionaryByAttribute(string keyAttribute, string valueAttribute, XmlNodeList elemlist)
    {
        Dictionary<string, string> dict = new Dictionary<string, string>();

        foreach (XmlNode item in elemlist)
        {
            foreach (XmlNode childNode in item.ChildNodes)
            {
                var dictKey = childNode.Attributes[keyAttribute].Value;
                var dictVal = childNode.Attributes[valueAttribute].Value;
                dict.Add(dictKey, dictVal);
            }
        }
        return dict;
    }


    public static string DictToString<T>(IDictionary<string, T> items, string format)
    {
        format = String.IsNullOrEmpty(format) ? "{0}='{1}' " : format;

        StringBuilder itemString = new StringBuilder();
        foreach (var item in items)
            itemString.AppendFormat(format, item.Key, item.Value);

        return itemString.ToString();
    }