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