使用Newtonsoft.Json.JsonSerializer将JSON转换为XDocument

时间:2017-09-13 11:14:54

标签: c# .net json xml json.net

我可以使用默认实现从JSON转换为XML,反之亦然。

但是,Json.Net使用AppBarLayout,为XML属性添加前缀。只能使用@在JavaScript中访问此内容。出于性能原因,我使用自定义root['@myAttribute']重命名属性,而是使用JsonTextWriter作为前缀,以便我可以使用$访问它们。

我的自定义JsonTextWriter

root.$myAttribute

用法

public class CustomJsonTextWriter : JsonTextWriter
{
    public CustomJsonTextWriter(TextWriter writer) : base(writer) { }

    public override void WritePropertyName(string propertyName)
    {
        if (propertyName.StartsWith("@"))
            base.WritePropertyName("$" + propertyName.Substring(1));
        else
            base.WritePropertyName(propertyName);
    }
}

从这一点来说,我能够非常有效地以所需的JSON格式(前缀为希望的属性)从XML转换。

问题

反向转换时出现问题,JSON转换为XML,因为应该是XML属性的字段(前缀为public static string ConvertXDocumentToJson(XDocument xDoc) { // Usage of the CustomJsonTextWriter to write the XML doc in JSON format prefixing attributes with "$" instead of "@". var builder = new StringBuilder(); JsonSerializer.Create().Serialize(new CustomJsonTextWriter(new StringWriter(builder)), xDoc); return builder.ToString(); } )仍然以@为前缀。

我知道有一些方法可以通过使用Regex和String.replace来解决这个问题,但我不希望在进行转换之前再次读取整个JSON。

首选解决方案

我希望有$可以输出XML,但是通过指定前缀char是“$”而不是“@”。我期待一种类的重写(JsonTextReader),我可以做类似的事情:

CustomJsonTextReader

1 个答案:

答案 0 :(得分:1)

看起来你需要JsonTextReader来反向...

阅读器

public class CustomJsonReader : JsonTextReader
{
    public CustomJsonReader(TextReader reader) : base(reader) { }

    public override object Value
    {
        get
        {
            if (TokenType != JsonToken.PropertyName)
            {
                return base.Value;
            }

            var propertyName = base.Value.ToString();

            if (propertyName.StartsWith("$"))
            {
                return $"@{propertyName.Substring(1)}";
            }
            else
            {
                return base.Value;
            }
        }
    }
}

用法

var xmlDoc = JsonSerializer.Create().Deserialize<XmlDocument>(
    new CustomJsonReader(new StringReader(json)));

// get the string value if needed...
var builder = new StringBuilder();
xmlDoc.Save(new StringWriter(builder ));

var xml = outbuilder.ToString();