【问题标题】:Keep json:Array attribute when converting XML to JSON to XML将 XML 转换为 JSON 到 XML 时保留 json:Array 属性
【发布时间】:2018-07-23 15:18:24
【问题描述】:

我有一段看起来像

的 XML
<person xmlns:json='http://james.newtonking.com/projects/json' id='1'>
   <name>Alan</name>
   <url>http://www.google.com</url>
   <role json:Array='true'>Admin</role>
</person>

当我尝试将其序列化为 json string json = JsonConvert.SerializeXmlNode(xml); 时,它会忽略命名空间

 {
  "person": {
    "@id": "1",
    "name": "Alan",
    "url": "http://www.google.com",
    "role": [
      "Admin"
    ]
  }
}

当我将其反序列化回 xml XmlDocument xml = JsonConvert.DeserializeXmlNode(json) 时,我得到以下信息:

<person id='1'>
 <name>Alan</name>
  <url>http://www.google.com</url>
  <role>Admin</role>
</person>

如何保留json:Array 属性?

【问题讨论】:

  • @Alok 在那个问题中没有找到我的问题的一个答案,只有标题是相关的。
  • 你能把从XMl转换过来的json数据也包含进去吗?
  • 我不确定它是否有用,这是我找到的唯一页面:newtonsoft.com/json/help/html/ConvertingJSONandXML.htm
  • 在将 JSON 转为 XML 时,我没有看到在 XML 中填充属性“Id”
  • 变量xml的值在哪里?试试看这个newtonsoft.com/json/help/html/CustomJsonConverter.htm。该答案明确指出您需要在设置的 xml 变量字符串前面添加一个 @ 符号。您的代码示例未显示您如何将 xml 读入变量。

标签: c# json xml json.net


【解决方案1】:

DeserializeXmlNode 的重载接受名为 writeArrayAttribute 的布尔标志。这就是你需要的:

XmlDocument xml = JsonConvert.DeserializeXmlNode(json, null, true);

生产:

<person id="1">
    <name>Alan</name>
    <url>http://www.google.com</url>
    <role xmlns:json="http://james.newtonking.com/projects/json" json:Array="true">Admin</role>
</person>

这在语义上与原始 xml 相同。

【讨论】:

    【解决方案2】:

    XML 到 JSON 会丢失名称中包含“:”(冒号)的所有属性的所有信息。这就是为什么 'id' 被序列化为 @id 而 'xmlns:json' 在翻译中丢失的原因。

    如果您可以访问原始 XML,那么我建议您将冒号 (:) 替换为连字符 (-)。在这种情况下,XML 将是:

    <person xmlns-json='http://james.newtonking.com/projects/json' id='1'>
        <name>Alan</name>
        <url>http://www.google.com</url>
        <role json-Array='true'>Admin</role>
    </person>
    

    我已经检查过这个序列化和反序列化到相同的输入和输出。

    var xmlString = @"<person xmlns-json='http://james.newtonking.com/projects/json' id='1'><name>Alan</name><url>http://www.google.com</url><role json-Array='true'>Admin</role></person>";
    var xml = new XmlDocument();
    xml.LoadXml(xmlString);
    
    var json = JsonConvert.SerializeXmlNode(xml);
    
    var xmlDeserialized = JsonConvert.DeserializeXmlNode(json);
    xmlDeserialized.Should().NotBeNull();
    xmlDeserialized.ShouldBeEquivalentTo(xml); //All good
    

    【讨论】:

      【解决方案3】:

      也许问题不在于您如何序列化 xml 节点。 在序列化之前验证您是如何读取 xml 文件的。 能给我们看看吗?

      【讨论】:

      【解决方案4】:

      这可能是另一种方法custom json converter 有点长,但我认为它更有用

      代码

      public class CustomXmlToJsonConverter : JsonConverter
          {
              private readonly Type[] _types;
      
              public CustomXmlToJsonConverter(params Type[] types)
              {
                  _types = types;
              }
      
              public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
              {
                  JToken t = JToken.FromObject(value);
      
                  if (t.Type != JTokenType.Object)
                  {
                      t.WriteTo(writer);
                  }
                  else
                  {
                      JObject o = (JObject)t;
                      IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList();
      
                      o.AddFirst(new JProperty("Keys", new JArray(propertyNames)));
      
                      o.WriteTo(writer);
                  }
              }
      
              public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
              {
                  throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
              }
      
              public override bool CanRead
              {
                  get { return false; }
              }
      
              public override bool CanConvert(Type objectType)
              {
                  return _types.Any(t => t == objectType);
              }
          }
      

      用法

       string json = JsonConvert.SerializeObject(root,Formatting.Indented,new CustomXmlToJsonConverter(typeof(XElement)));
      

      结果

      {
        "Keys": [
          "person"
        ],
        "person": {
          "@json": "http://james.newtonking.com/projects/json",
          "@id": "1",
          "name": "Alan",
          "url": "http://www.google.com",
          "role": {
            "@Array": "true",
            "#text": "Admin"
          }
        }
      }
      

      样本数据

       XNamespace jsonPrefix1 = "xmlns";
       XNamespace jsonPrefix2 = "json";
       XElement root = new XElement("person",
       new XAttribute(jsonPrefix1 + "json", "http://james.newtonking.com/projects/json"),              
      new XAttribute("id","1"),
      new XElement("name", "Alan"), new XElement("url", "http://www.google.com"),
      new XElement("role" ,"Admin", new XAttribute(jsonPrefix2 + "Array", "true"))
      );
      

      【讨论】:

        猜你喜欢
        • 2016-10-26
        • 1970-01-01
        • 2021-10-26
        • 1970-01-01
        • 2014-04-29
        • 2016-08-09
        • 2020-03-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多