【问题标题】:Json.NET, can SerializeXmlNode be extended to detect numbers?Json.NET,可以扩展 SerializeXmlNode 来检测数字吗?
【发布时间】:2014-03-31 19:49:17
【问题描述】:

我正在使用 SerializeXmlNode 从 XML 转换为 JSON。看起来预期的行为是将所有 XML 值转换为字符串,但我想在适当的地方发出真正的数值。

// Input:   <Type>1</Type>
string json = JsonConvert.SerializeXmlNode(node, Newtonsoft.Json.Formatting.Indented, true);
// Output:  "Type": "1"
// Desired: "Type": 1

我是否需要编写一个自定义转换器来执行此操作,或者是否有办法通过委托在适当的点挂钩到序列化过程?或者,我必须编写自己的自定义 JsonConverter 类来管理转换吗?

正则表达式破解

考虑到正确解决方案的复杂性,这里有另一个(我并不完全为它感到自豪,但它确实有效......)。

// Convert to JSON, and remove quotes around numbers
string json = JsonConvert.SerializeXmlNode(node, Newtonsoft.Json.Formatting.Indented, true);

// HACK to force integers as numbers, not strings.
Regex rgx = new Regex("\"(\\d+)\"");
json = rgx.Replace(json, "$1");

【问题讨论】:

    标签: c# json.net


    【解决方案1】:

    XML 无法像 JSON 那样区分原始类型。因此,在将 XML 直接转换为 JSON 时,Json.Net 不知道值应该是什么类型,无法猜测。如果它总是假设仅由数字组成的值是序数,那么像邮政编码和带有前导零的电话号码之类的东西会在转换中被破坏。那么,Json.Net 走安全的道路并将所有值都视为字符串也就不足为奇了。

    解决此问题的一种方法是将您的 XML 反序列化为中间对象,然后将其序列化为 JSON。由于中间对象具有强类型属性,因此 Json.Net 知道要输出什么。这是一个例子:

    class Program
    {
        static void Main(string[] args)
        {
            string xml = @"<root><ordinal>1</ordinal><postal>02345</postal></root>";
    
            XmlSerializer xs = new XmlSerializer(typeof(Intermediary));
            using (TextReader reader = new StringReader(xml))
            {
                Intermediary obj = (Intermediary)xs.Deserialize(reader);
                string json = JsonConvert.SerializeObject(obj , Formatting.Indented);
                Console.WriteLine(json);
            }
        }
    }
    
    [XmlRoot("root")]
    public class Intermediary
    {
        public int ordinal { get; set; }
        public string postal { get; set; }
    }
    

    以上输出:

    {
      "ordinal": 1,
      "postal": "02345"
    }
    

    要制定更通用的解决方案,是的,您必须编写自己的转换器。事实上,调用 SerializeXmlNode 时发生的 XML 到 JSON 的转换是使用 Json.Net 附带的 XmlNodeConverter 完成的。这个转换器本身似乎不是很可扩展,但您始终可以使用它的source code 作为起点来创建自己的。

    【讨论】:

    • 我就是这么想的。不过,获得第二意见是件好事。感谢您的彻底回应!
    • 没问题;很高兴我能帮上忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 2010-10-07
    • 2020-09-10
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 2014-07-01
    相关资源
    最近更新 更多