如何将 XML 片段转换为 C# 中的字典?

How can I convert an XML fragment to a Dictionary in C#?

我有以下 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();                       
}

试试这个...

以下代码将为您提供一个包含 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

你的真正的问题是你想生成一个 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);

会 return 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();

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

已更新

按照您的意愿进行了操作,但是...我认为您的请求有误...仔细查看“35=U149=GEMI18=FIX.4.19=732”这个 gona 知道 GEMI18 实际上是 GEMI1 [space] 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();
    }