【问题标题】:Convert empty arrays from JSON to XML with Json.NET (Newtonsoft)使用 Json.NET (Newtonsoft) 将空数组从 JSON 转换为 XML
【发布时间】:2021-03-16 02:29:06
【问题描述】:

鉴于以下 JSON:

string json = @"
  {
    ""Identifier"": ""MyID"",
    ""Data"": []
  }";

如果我使用XDocument xDocument = JsonConvert.DeserializeXNode(json, "Foo"); 将其转换为 XML,则生成的 XML 为:

  <Foo>
    <Identifier>MyID</Identifier>
  </Foo>

我想要的输出是这样的:

  <Foo>
    <Identifier>MyID</Identifier>
    <Data/>
  </Foo>

是否有序列化程序设置或我可以用来进行此更改的东西?

编辑:为清楚起见 - 我正在寻找一个通用的解决方案,但不提前知道 JSON 的结构。目标是简单地将任意 JSON 转换为 XML,而不会省略空数组的标签。

【问题讨论】:

    标签: c# json .net xml json.net


    【解决方案1】:

    我认为这 issue 将是您看到的行为的原因。似乎归结为 xml 如何表示数组:节点只是重复

    void Main()
    {
        JsonConvert.DeserializeXNode(@" {""Identifier"": ""MyID"", ""Data"": [1,2,3]}", "Foo", true, false);
        /*
            <Foo>
              <Identifier>MyID</Identifier>
              <Data>1</Data>
              <Data>2</Data>
              <Data>3</Data>
            </Foo>
        */
        JsonConvert.DeserializeXNode(@" {""Identifier"": ""MyID"", ""Data"": [null]}", "Foo", true, false); // this seems to be the closest to what you are after, but it is semantically different from empty array
        /*
        <Foo>
          <Identifier>MyID</Identifier>
          <Data json:Array="true" xmlns:json="http://james.newtonking.com/projects/json" />
        </Foo>
        */
        JsonConvert.DeserializeXNode(@" {""Identifier"": ""MyID"", ""Data"": []}", "Foo", true, false);
        /*
        <Foo>
          <Identifier>MyID</Identifier>
        </Foo>
        */
    }
    

    【讨论】:

      【解决方案2】:

      以下示例假设您有一个名为 Form1 (Form1.cs) 的表单。

      尝试以下方法:

      安装 Newtonsoft NuGet 包

      • 在菜单上,查看
      • 选择解决方案资源管理器
      • 在解决方案资源管理器中,右键单击
      • 选择管理 NuGet 包...
      • 点击浏览
      • 搜索:Newtonsoft.Json
      • 点击Newtonsoft.Json
      • 点击安装

      创建一个名为 Foo 的类

      Foo.cs

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using System.Xml.Serialization;
      
      namespace NewtonsoftEmptyXmlElement
      {
          [XmlRoot(ElementName = "Foo")]
          public class Foo
          {
              [XmlElementAttribute(ElementName = "Identifier")]
              public string Identifier { get; set; }
      
              [XmlArrayAttribute("Data")]
              public List<string> Data { get; set; } = new List<string>();
          }
      }
      

      Form1.cs

      添加以下 using 语句:

      using Newtonsoft.Json;
      using System.Xml;
      using System.Diagnostics;
      using System.IO;
      using System.Xml.Serialization;
      

      GenerateXml(将 XML 作为字符串返回)

      public static string GenerateXml<T>(object obj, System.Text.Encoding encoding)
      {
          string xml = string.Empty;
      
          using (MemoryStream ms = new MemoryStream())
          {
              XmlSerializer serializer = new XmlSerializer(typeof(T));
      
              //eliminate "xsd" and "xsi" namespaces
              XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
              ns.Add("", "");
      
              //indent Xml and eliminate Xml declaration
              XmlWriterSettings writerSettings = new XmlWriterSettings();
              writerSettings.OmitXmlDeclaration = true;
              writerSettings.Encoding = encoding;
              writerSettings.Indent = true;
      
      
              //create instance of XmlWriter
              XmlWriter writer = XmlWriter.Create(ms, writerSettings);
      
              serializer.Serialize(writer, (T)obj, ns);
             
              xml = encoding.GetString(ms.ToArray());
      
          }
      
          return xml;
      }
      

      WriteXML(将 XML 写入文件)

      public static void WriteXml<T>(object obj, string filename, System.Text.Encoding encoding)
      {
          string xml = string.Empty;
      
          try
          {
              using (StreamWriter fs = new StreamWriter(filename))
              {
                  XmlSerializer serializer = new XmlSerializer(typeof(T));
      
                  //eliminate "xsd" and "xsi" namespaces
                  XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                  ns.Add("", "");
      
                  //indent Xml and eliminate Xml declaration
                  XmlWriterSettings writerSettings = new XmlWriterSettings();
                  writerSettings.OmitXmlDeclaration = true;
                  writerSettings.Encoding = encoding;
                  writerSettings.Indent = true;
      
      
                  //create instance of XmlWriter
                  XmlWriter writer = XmlWriter.Create(fs, writerSettings);
      
                  serializer.Serialize(writer, (T)obj, ns);
      
              }
          }
          catch(Exception ex)
          {
              System.Diagnostics.Debug.WriteLine("Error: - " + ex.Message);
          }
          
      }
      

      测试

      private void Test()
      {
          string json = @"
          {
              ""Identifier"": ""MyID"",
              ""Data"": []
          }";
      
          //System.Diagnostics.Debug.WriteLine(json);
          Foo foo2 = Newtonsoft.Json.JsonConvert.DeserializeObject<Foo>(json, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Include });
      
          //Option 1 - get XML
          string xmlDoc = GenerateXml<Foo>(foo2, System.Text.Encoding.UTF8); 
          System.Diagnostics.Debug.WriteLine("\n\n" + xmlDoc);
      
          //Option 2 - write XML to file
          WriteXml<Foo>(foo2, @"C:\Temp\foo.xml", System.Text.Encoding.UTF8);
      }
      

      使用方法:

      Test();
      

      输出:

      <Foo>
        <Identifier>MyID</Identifier>
        <Data />
      </Foo>
      

      【讨论】:

      • 请查看已编辑的问题。这个解决方案需要我为 JSON 创建一个类。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-25
      相关资源
      最近更新 更多