You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中无需模型保留数据类型实现XML转JSON的问题

解决C#中XML转JSON保留数据类型的问题

问题场景

源XML结构:

<Employee >
  <Name>John</Name>
  <Age>18</Age>
  <IsContractor>true</IsContractor>
  <Salary>5555.66</Salary>
</Employee>

期望转换后的JSON保留原始数据类型:

"Employee": {
      "Name": "John",
      "Age": 18,
      "IsContractor": true,
      "Salary": 5555.66
    }

尝试以下两种方法后,所有值仍被转为字符串:

尝试方法一

string xml = @"<Employee>
                            <Name>John</Name>
                            <Age json:Type='Integer'>18</Age>
                            <IsContractor json:Type='Boolean'>true</IsContractor>
                            <Salary json:Type='Decimal'>5555.66</Salary>
                        </Employee>";
  
var doc = new XmlDocument();
doc.LoadXml(xml);
var result = JsonConvert.SerializeXmlNode(doc);

尝试方法二

var xml = @"<Employee  xmlns:m=""urn:informatica:ae:xquery:json2xml:meta-data"">
                    <Name>John</Name>
                    <Age m:type=""xs:double"">18</Age>
                    <IsContractor m:type=""xs:boolean"">true</IsContractor>
                     </Employee>";
var doc = new XmlDocument();
doc.LoadXml(xml);
var result1 = JsonConvert.SerializeXmlNode(doc);

可行解决方案

方案1:实体类中转法(推荐)

通过强类型实体类先序列化XML,再转换为JSON,天然保留数据类型:

  1. 定义对应实体类:
public class Employee
{
    public string Name { get; set; }
    public int Age { get; set; }
    public bool IsContractor { get; set; }
    public decimal Salary { get; set; }
}
  1. 执行转换逻辑:
var xml = @"<Employee>
  <Name>John</Name>
  <Age>18</Age>
  <IsContractor>true</IsContractor>
  <Salary>5555.66</Salary>
</Employee>";

XmlSerializer serializer = new XmlSerializer(typeof(Employee));
Employee employee;
using (StringReader reader = new StringReader(xml))
{
    employee = (Employee)serializer.Deserialize(reader);
}

// 生成符合预期的JSON结构
string json = JsonConvert.SerializeObject(new { Employee = employee }, Formatting.Indented);

方案2:手动遍历XmlNode转换类型

若无法定义实体类,可遍历节点手动解析值的类型:

var doc = new XmlDocument();
doc.LoadXml(xml);
var employeeNode = doc.SelectSingleNode("Employee");

var jObj = new JObject();
foreach (XmlNode node in employeeNode.ChildNodes)
{
    if (node.NodeType != XmlNodeType.Element) continue;
    
    switch (node.Name)
    {
        case "Age":
            jObj.Add(node.Name, int.Parse(node.InnerText));
            break;
        case "IsContractor":
            jObj.Add(node.Name, bool.Parse(node.InnerText));
            break;
        case "Salary":
            jObj.Add(node.Name, decimal.Parse(node.InnerText));
            break;
        default:
            jObj.Add(node.Name, node.InnerText);
            break;
    }
}

string json = JsonConvert.SerializeObject(new { Employee = jObj }, Formatting.Indented);

方案3:正确使用Json.NET的类型属性

之前的方法一未添加正确的命名空间,导致json:Type属性不生效,修正后即可:

  1. 修改XML添加Json.NET专属命名空间:
<Employee xmlns:json="http://james.newtonking.com/projects/json">
  <Name>John</Name>
  <Age json:Type='Integer'>18</Age>
  <IsContractor json:Type='Boolean'>true</IsContractor>
  <Salary json:Type='Decimal'>5555.66</Salary>
</Employee>
  1. 执行转换:
var doc = new XmlDocument();
doc.LoadXml(xml);
var converter = new XmlNodeConverter { OmitRootObject = false };
string json = JsonConvert.SerializeObject(doc, converter);

内容的提问来源于stack exchange,提问作者CodeSmith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 18:23:08