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



当我使用包含如下数组的 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>

为了使这更加复杂,我正在尝试在框架代码中执行此操作,所以我真的不知道传入的数据是什么,这意味着我不知道如何称呼子元素,但也许一次只有一个问题:)。

以下自定义 XmlNodeConverter 将序列化单个节点下的数组,每个数组元素都分配一个指定的名称。鉴于您不知道传入的数据,您可以选择一个通用名称,例如"Element",在这种情况下,您的示例 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);

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

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

相关内容

  • 没有找到相关文章

最新更新