xml - 挑战 : Can you make this simple function more elegant using C# 4. 0

标签 xml c#-4.0

当我破解我们的代码库时,我刚刚注意到这个函数。它转换 IDictionary<string, object> (Paramters - 实例变量) 转换为 XML 字符串。

这只是我的好奇心:-)。

那么它是否可以使用 C# 4.0 用更少的代码编写?规则:除了 .Net Framework BCL 之外没有外部库。

为了让它更具挑战性,我没有将输入字典规范放在这里,因为您应该能够从代码中解决它。

public string ConvertToXml() {
    XmlDocument doc = new XmlDocument();
    doc.LoadXml("<?xml version='1.0' encoding='utf-8'?><sc/>");
    foreach (KeyValuePair<string, object> param in Parameters) {
        XmlElement elm = doc.CreateElement("pr");

        if (param.Value is int || param.Value is Int32 || param.Value is Int16 || param.Value is Int64) {
            elm.SetAttribute("tp", "int");
        } else if (param.Value is DateTime?){
            elm.SetAttribute("tp", "datetime");
        } else {
            elm.SetAttribute("tp", "string");
        }

        elm.SetAttribute("nm", param.Key);
        if (param.Value is DateTime?) {
            DateTime? dateTime = param.Value as DateTime?;
            elm.SetAttribute("vl", dateTime.Value.ToString("o"));
        } else{
            elm.SetAttribute("vl", param.Value.ToString());
        }
        doc.FirstChild.NextSibling.AppendChild(elm);
    }
    return doc.OuterXml;
}

让我补充一些想法。

对我来说:

  • 少即是多,但简洁是不好的
  • 类型越多越好,但琐碎的类型看起来很臭
  • 复用性好

最佳答案

使用 LINQ to XML 可以使编写起来非常简单。如果可以选择,请优先使用它而不是标准 XML 库。

我相信这应该是等价的:

public static string ToXmlString(this IDictionary<string, object> dict)
{
    var doc = new XDocument(new XElement("sc", dict.Select(ToXElement)));

    using (var writer = new Utf8StringWriter())
    {
        doc.Save(writer); // "hack" to force include the declaration
        return writer.ToString();
    }
}

class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding { get { return Encoding.UTF8; } }
}

static XElement ToXElement(KeyValuePair<string, object> kvp)
{
    var value = kvp.Value ?? String.Empty;

    string typeString;
    string valueString;
    switch (Type.GetTypeCode(value.GetType()))
    {
    case TypeCode.Int16:
    case TypeCode.Int32:
    case TypeCode.Int64:
        typeString = "int";
        valueString = value.ToString();
        break;
    case TypeCode.DateTime:
        typeString = "datetime";
        valueString = ((DateTime)value).ToString("o");
        break;
    default:
        typeString = "string";
        valueString = value.ToString();
        break;
    }

    return new XElement("pr",
        new XAttribute("tp", typeString),
        new XAttribute("nm", kvp.Key),
        new XAttribute("vl", valueString));
}

注意检查值的类型是否为DateTime?毫无意义。我不确定存储 null 有什么值(value)字典中的值,但如果可能的话,由于生成 object 类型的值,您无论如何都会丢失该类型信息.

此外,如果有 DateTime?不是 null 的值,则值本身将被装箱,而不是 Nullable<DateTime>结构本身。所以实际类型是 DateTime这就是此代码有效的原因。

关于xml - 挑战 : Can you make this simple function more elegant using C# 4. 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7071238/

相关文章:

java - 加载自定义 Android View 时出错 : Resources$NotFoundException: Resource ID #0x7f060007 type #0x12 is not valid

c# - 访问扩展器控件的子级

algorithm - C# 中的冒泡排序

c# - 使用 C# 代码格式化完整地址

c# - 动态嵌套循环

Java:迭代 XML 文件 - hasChildNodes() 测试未按我的想象工作

java - Android rss 无法解析带有属性的 XML

xml - NodeJS xpath 库是否支持 XPath 查询表达式?

c# - 在 Asp.net C# 中使用文件上传将数据从 .csv 导入 SQL Server

xml - Xquery 中的分组和计数