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

Posted

技术标签:

【中文标题】将 XML 转换为 JSON 到 XML 时保留 json:Array 属性【英文标题】:Keep json:Array attribute when converting XML to JSON to XML 【发布时间】: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 读入变量。 【参考方案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 文件的。 能给我们看看吗?

【讨论】:

这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review 感谢@MickyD 的建议【参考方案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"))
);

【讨论】:

以上是关于将 XML 转换为 JSON 到 XML 时保留 json:Array 属性的主要内容,如果未能解决你的问题,请参考以下文章

PHP - xml到json转换:“无法将字符串解析为XML”

如何使用 C#/LINQ 将 XML 转换为 JSON?

将 XML 响应转换为 Json 时出错

将单个xml节点作为数组转换为json

PHP将带有一些(重复)元素的XML转换为Json到Json数组[重复]

将 XML 转换为 JSON 时如何解决编码问题?