我有一个Web服务,它正在解析JSON请求并使用值来设置XML文档的属性。
例如,以下请求
{ name: "Foo", isEnabled: true, size: 100 }
应该将XML文档更新为
<SomeElement name="Foo" isEnabled="true" size="100" />
但它产生了这个:
<SomeElement name="Foo" isEnabled="True" size="100" />
我没有JSON输入的结构化类型或我修改的XML(我在这里的中间人),所以我将JSON解析为JObject
并且XML是原始的XmlDocument
。
问题是,当我浏览JObject
时,我得到每个属性JValue并将其转换为字符串,通过调用JValue.ToString()
将其放入XML属性中。对于整数和字符串值,这工作正常,但对于布尔值,JValue.ToString()
导致True/False
,而不是true/false
,因此当XML文档的用户尝试解析XML文档时在它们的对象中,它失败了,因为True
是一个无效的布尔值。
另一方面,如果我使用JsonConvert.SerializeObject()
来转换值,那么布尔和整数将起作用,但字符串值将被引用(根据JSON的要求)。
有没有更好的方法来获得我需要的正确的stringed值,或者我只需要在转换代码中使用特殊情况boolean JValue
?
答案 0 :(得分:1)
您可以为JValue
创建一个扩展方法,以提供您想要的结果:
public static class JsonExtensions
{
public static string ToXmlFriendlyString(this JValue jv)
{
return (jv.Type == JTokenType.Boolean ? jv.ToString().ToLower() : jv.ToString());
}
}
然后,无论您在哪里呼叫JValue.ToString()
,都要调用扩展方法,例如:
JValue jv = new JValue(true);
Console.WriteLine(jv.ToXmlFriendlyString());
答案 1 :(得分:1)
您需要的逻辑位于XmlNodeConverter.ConvertTokenToXmlValue()
,根据JSON令牌类型调用正确的XmlConvert.ToString()
重载。不幸的是,它不公开。访问此方法的最简单方法(除了复制它的逻辑之外)是创建包含JObject
的临时JValue
,并使用XmlNodeConverter
将其转换为XElement
,然后返回创建的XElement
:
public static class JsonExtensions
{
public static string ToXmlValue(this JValue value)
{
if (value == null)
return null;
var obj = new JObject(new JProperty("a", value.DeepClone())); // XmlNodeConverter only works deserializing an object, so make a synthetic object.
return obj.ToXElement().Value;
}
public static XElement ToXElement(this JObject obj)
{
if (obj == null)
return null;
using (var reader = obj.CreateReader())
return JsonExtensions.DeserializeXElement(reader);
}
public static XElement DeserializeXElement(JsonReader reader)
{
return DeserializeXElement(reader, null, false);
}
public static XElement DeserializeXElement(JsonReader reader, string deserializeRootElementName, bool writeArrayAttribute)
{
var converter = new Newtonsoft.Json.Converters.XmlNodeConverter() { DeserializeRootElementName = deserializeRootElementName, WriteArrayAttribute = writeArrayAttribute };
var jsonSerializer = JsonSerializer.CreateDefault(new JsonSerializerSettings { Converters = new JsonConverter[] { converter } });
return jsonSerializer.Deserialize<XElement>(reader);
}
}
这应该正确处理所有到XML的值类型转换 - DateTime
,bool
,decimal
等等 - 正确的国际化。
您可能还想查看Converting between JSON and XML,了解Json.NET的内置转换API是否可以为您提供帮助。