如何让JsonConvert.DeserializeXmlNode在单个节点下序列化数组?

时间:2014-03-03 19:31:47

标签: .net json.net

当我使用包含如下数组的JSON字符串调用JsonConvert.DeserializeXmlNode时:

{"Name":"Brian","Wife":{"Name":"Christine"},"Children":[{"Name":"Kiara"},{"Name":"Abrian"},{"Name":"Brooke"}]}

我得到的XML看起来像这样:

<Root>
  <Name>Brian</Name>
  <Wife>
    <Name>Christine</Name>
  </Wife>
  <Children>
    <Name>Kiara</Name>
  </Children>
  <Children>
    <Name>Abrian</Name>
  </Children>
  <Children>
    <Name>Brooke</Name>
  </Children>
</Root>

我想要的是这样的东西:

<Root>
  <Name>Brian</Name>
  <Wife>
    <Name>Christine</Name>
  </Wife>
  <Children>
    <Child>
      <Name>Kiara</Name>
    </Child>
    <Child>
      <Name>Abrian</Name>
    </Child>
    <Child>
      <Name>Brooke</Name>
    </Child>
  </Children>
</Root>

为了使这更复杂,我试图在框架代码中这样做,所以我真的不知道数据是什么,这意味着我不知道该怎么称为子元素,但是也许一次只有一个问题:)。

2 个答案:

答案 0 :(得分:2)

以下自定义XmlNodeConverter将在单个节点下序列化数组,并为每个数组元素分配指定的名称。如果你不知道传入的数据,你可以选择像#34; Element&#34;这样的通用名称,在这种情况下你的示例json会转换为:

<Children>
   <Element>
      <Name>Christine</Name>
   </Element>
   <Element>
      <Name>Kiara</Name>
   </Element>
</Children>

自定义XmlNodeConverter:

public class SingleArrayNodeXmlConverter : XmlNodeConverter
{
    public string ArrayElementName { get; set; }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var token = JObject.Load(reader);
        InjectArrayElements(token, ArrayElementName);
        var innerReader = token.CreateReader();
        innerReader.Read();
        return base.ReadJson(innerReader, objectType, existingValue, serializer);
    }

    private static void InjectArrayElements(JToken token, string elementName)
    {
        foreach (var childToken in token)
        {
            InjectArrayElements(childToken, elementName);
        }
        if (token.Type == JTokenType.Array)
        {
            var arrayHolder = new JObject { { elementName, token } };
            token.Replace(arrayHolder);
        }
    }
}

用法:

var converter = new SingleArrayNodeXmlConverter
{
    DeserializeRootElementName = "Root",
    WriteArrayAttribute = false,
    ArrayElementName = "Element"
};
return (XmlDocument)JsonConvert.DeserializeObject(json, typeof(XmlDocument), converter);

这个解决方案显然是一个妥协,但在我们的情况下,即使是通用数组元素也比重复数组节点本身更好。

答案 1 :(得分:-2)

{"Name":"Brian","Wife":{"Name":"Christine"},"Children":["Child":{"Name":"Kiara"},"Child":{"Name":"Abrian"},"Child":{"Name":"Brooke"}]}