【问题标题】:Convert JSON to XDocument using Newtonsoft.Json.JsonSerializer使用 Newtonsoft.Json.JsonSerializer 将 JSON 转换为 XDocument
【发布时间】:2018-02-22 01:52:30
【问题描述】:

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

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

我的自定义 JsonTextWriter

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);
    }
}

用法

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();            
}

从这一点开始,我能够非常有效地从 XML 转换为所需的 JSON 格式(根据需要添加前缀属性)。


问题

在反向转换 JSON 到 XML 时出现问题,因为应该是 XML 属性的字段(以 @ 为前缀)仍然以 $ 为前缀。

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

首选解决方案

我想要一个CustomJsonTextReader,它可以输出一个XML,但是通过指定前缀字符是“$”而不是“@”。我期待一种类(JsonTextReader)的覆盖,我可以在其中做类似的事情:

public override void ReadPropertyName(string propertyName)
{
    // pseudo-code
    if(propertyName.startsWith("$")) // instead of "@"
        CreateXmlAttribute(propertyName.substring(1));
}

【问题讨论】:

  • 如果 StackCodeReview 仅用于代码审查,则否。我想找到一种解决方案,了解如何为 JSON 到 XML 编写一个自定义转换器,该转换器尊重/模仿 Newtonsoft 当前使用的转换器。
  • 你是如何公开你的 API 的?如果是通过 WebAPI,您无需执行任何操作。 WebAPI 查看请求的Accept-Encoding 标头并返回正确的格式。
  • 您的代码虽然不能满足您的需求,但可以正常工作,但这就是代码审查可以帮助您的地方,您可以不用担心重复提出这个问题。 SO 不是为您提供代码编写服务
  • @MichaelCoxon 问题不在于公开 API,而在于读取 JSON,其中字段以“$”而不是“@”为前缀,以将它们转换为 XML 属性。想象一下,这种情况可能只意味着读取本地文件。
  • 好的,那么你为什么在 JSON 前加上“$”是有原因的吗?似乎(从我可以从问题中收集到的信息)您这样做的唯一原因是您可以使用 JavaScript 对象表示法访问该对象

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


【解决方案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();

【讨论】:

  • 这非常有效,非常感谢您的时间、解释和编辑@MichaelCoxon!
猜你喜欢
  • 1970-01-01
  • 2014-01-17
  • 2010-10-19
  • 1970-01-01
  • 2014-08-08
  • 2014-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多