将XML转换为JSON时保留json:Array属性

时间:2018-02-13 09:42:04

标签: c# json xml json.net

我有一段看起来像

的XML
selectInput

当我尝试将其序列化为json <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> 时,它会忽略名称空间

string json = JsonConvert.SerializeXmlNode(xml);

当我将其反序列化回xml { "person": { "@id": "1", "name": "Alan", "url": "http://www.google.com", "role": [ "Admin" ] } } 时,我得到以下内容:

XmlDocument xml = JsonConvert.DeserializeXmlNode(json)

如何保留<person id='1'> <name>Alan</name> <url>http://www.google.com</url> <role>Admin</role> </person> 属性?

4 个答案:

答案 0 :(得分:7)

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完全相同。

答案 1 :(得分:2)

XMl到JSon会丢失名称中包含':'(冒号)的任何属性的所有信息。这就是为什么'id'被序列化为@id但是'xmlns:json'在翻译中丢失了。

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

DB::beginTransaction();
try {
  // First query
  // Second query
  ..........
  DB::commit();   
} catch (Exception $ex) {
  DB::rollback();
}

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

<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>

答案 2 :(得分:1)

问题可能不是你如何序​​列化xml节点。 在序列化之前验证您如何读取xml文件。 你能告诉我们吗?

答案 3 :(得分:1)

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

代码

DELETE
  

用法

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"
    }
  }
}