将布尔值JValue转换为可解析的布尔字符串

时间:2015-10-19 19:07:00

标签: xml json.net

我有一个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

2 个答案:

答案 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的值类型转换 - DateTimebooldecimal等等 - 正确的国际化。

您可能还想查看Converting between JSON and XML,了解Json.NET的内置转换API是否可以为您提供帮助。