【问题标题】:How to deal single element json array when converting sql xml to json convertion in c#?在c#中将sql xml转换为json转换时如何处理单元素json数组?
【发布时间】:2019-04-25 18:56:38
【问题描述】:

我正在使用 C# 将 SQL 输出 XML 转换为 JSON 转换。当我将具有多个集合元素的 XML 转换为 JSON 时,像 JSON 数组一样的输出同时 XML 有单个集合,然后像 JSON 对象一样输出。在这两种情况下,如何将输出保持为 JSON 数组?

案例一:

<root>
   <DATA>
    <NAME>NAYAN</NAME>
    <LOCATION>CHENNAI</LOCATION>
  </DATA>
   <DATA>
    <NAME>TARA</NAME>
    <LOCATION>CHENNAI</LOCATION>
  </DATA>
 </root> 

结果:

{
   "DATA": [
      {
         "NAME": "NAYAN",
         "LOCATION": "CHENNAI"
      },
      {
         "NAME": "TARA",
         "LOCATION": "CHENNAI"
      }
   ]
}

案例 2:

<root>
   <DATA>
    <NAME>NAYAN</NAME>
    <LOCATION>CHENNAI</LOCATION>
  </DATA>
 </root>

结果:

{
   "DATA": {
      "NAME": "NAYAN",
      "LOCATION": "CHENNAI"
   }
}

期望:

{
   "DATA":[
 {
      "NAME": "NAYAN",
      "LOCATION": "CHENNAI"
   }
]
}

这是我的 C# 代码:

static void Main(string[] args)
{
    string xml = @"<root>
      <DATA>
        <NAME>NAYAN</NAME>
        <LOCATION>CHENNAI</LOCATION>
      </DATA>
    </root>";

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(xml);

    string json = JsonConvert.SerializeXmlNode(doc,Newtonsoft.Json.Formatting.Indented,true);

    Console.WriteLine(json);
}

【问题讨论】:

  • 请问您能显示您正在使用的代码吗?
  • @JonSkeet 当然。现在我已经在我的问题中添加了代码。
  • 好的。结构总是一样的吗?如果是这样,我个人会直接迭代 XML(虽然我会使用 LINQ to XML 而不是XmlDocument)并创建一个JArray。这将是非常简单的代码 - 但如果您需要它来处理不同的结构,它将无法工作。
  • @ArulmuruganK,如果对您有帮助,我在下面添加了我的答案,然后在答案左侧打勾以使其变为绿色

标签: c# .net json xml


【解决方案1】:

在这里我创建了一个简单的实用函数,如果DATA 包含对象或数组,它可以获取您的DATA 令牌并将其解析为数组。

public class Utility
{
    public static string JsonParser(string json)
    {
        JToken jTokenMain = JToken.Parse(json);

        JToken jToken = jTokenMain["DATA"];

        List<object> list = new List<object>();

        if (jToken is JArray)
        {
            list = jToken.ToObject<List<object>>();
        }
        else if (jToken is JObject)
        {
            list.Add(jToken.ToObject<object>());
        }

        JToken data = JToken.FromObject(list);

        jTokenMain["DATA"] = data;

        return jTokenMain.ToString();
    }
}

你可以使用上面的函数

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

string json = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented, true);

string formattedJson = Utility.JsonParser(json);    

编辑:

在您的 xml 中,&lt;root&gt; 是第 0 级元素,&lt;DATA&gt; 是第 1 级元素,它的名称可以是任何东西,并且您希望此元素是 json 中的 Array,无论是它的对象还是 xml 中的数组。

XDocument doc = XDocument.Parse(xml);
//XDocument doc = XDocument.Load(@"Path to your xml");

Dictionary<string, object> dict = doc.Root.Elements()
   .GroupBy(x => x.Name.LocalName, y => new
   {
       Name = y.Element("NAME").Value,
       Location = y.Element("LOCATION").Value
   })
   .ToDictionary(x => x.Key, y => (object)y.ToList());

string json = JsonConvert.SerializeObject(dict);

Console.WriteLine(json);

案例1:(第一级元素名称为DATA

<root>
<DATA>
  <NAME>NAYAN</NAME>
  <LOCATION>CHENNAI</LOCATION>
</DATA>
</root>

输出:(键名为DATA的Json)

案例2:(第一级元素名称为SAMPLE

<root>
<SAMPLE>
  <NAME>NAYAN</NAME>
  <LOCATION>CHENNAI</LOCATION>
</SAMPLE>
</root>

输出:(键名为SAMPLE的Json)

【讨论】:

  • 我已经这样尝试了。但输入 XML 是从 SQL FOR XML PATH 生成的。所以元素名称是动态的。这有可能从sql中纠正它吗?
  • 你的意思是DATA, NAME, LOCATION 是动态的?
  • 我谈论像“DATA”这样的元素名称。我创建了一个结果元素为“DATA”的存储过程。在未来的客户想要添加新元素而不是我需要更改存储过程。这对我来说很容易,但我也需要更改 c# 代码。所以我的想法是需要在我的存储过程中指出“这是元素是 json”。 FOR XML PATH 特性有什么可能?
  • 意味着,在你的 xml 根是第 0 级元素,DATA 是第 1 级元素,它的名字可以是任何东西,你希望这个 elememt 是 json 中的数组,无论是它的对象还是 xml 中的数组,对吧?
  • 更新答案为时已晚。我明天可以更新。保持联系:)
猜你喜欢
  • 2016-06-09
  • 2017-09-30
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
  • 1970-01-01
  • 2021-08-11
  • 1970-01-01
  • 2016-07-03
相关资源
最近更新 更多