Json.NET中的XML实体

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Json.NET中的XML实体相关的知识,希望对你有一定的参考价值。

Json.NET支持将XML转换为XML和从XML转换。所以我尝试了这样的简单代码:

string xml = @"<?xml version='1.0' standalone='no'?>
    <!DOCTYPE notes [
        <!ENTITY ent 'Sample text'>
    ]>
    <notes>
        <note>&ent;</note>
    </notes>";

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string json = JsonConvert.SerializeXmlNode(doc);
Console.WriteLine(json);

结果会抛出异常:

Newtonsoft.Json.JsonSerializationException:
Unexpected XmlNodeType when getting node name: EntityReference

我找不到关于(非)支持实体的任何信息,所以也许我做错了什么?

答案

例外是解释性的:Json.NET显然没有实现XmlEntityReference节点到JSON的转换。这是XmlNode子类型,用于表示&ent; entity reference

为了避免这种限制,您需要在读取XML时扩展实体,例如:

var settings = new XmlReaderSettings
{
    // Allow processing of DTD
    DtdProcessing = DtdProcessing.Parse,
    // On older versions of .Net instead set 
    //ProhibitDtd = false,
    // But for security, prevent DOS attacks by limiting the total number of characters that can be expanded to something sane.
    MaxCharactersFromEntities = (long)1e7,
    // And for security, disable resolution of entities from external documents.
    XmlResolver = null,
};
XmlDocument doc = new XmlDocument();
using (var textReader = new StringReader(xml))
using (var xmlReader = XmlReader.Create(textReader, settings))
{
    doc.Load(xmlReader);
}
string json = JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented);
Console.WriteLine(json);

笔记:

或者您可以切换到XDocument API,其中实体始终展开,默认情况下安全设置更合适:

var doc = XDocument.Parse(xml);
string json = JsonConvert.SerializeXNode(doc, Newtonsoft.Json.Formatting.Indented);
Console.WriteLine(json);

工作.Net fiddle显示&ent;节点扩展到其值Sample text

{
  "?xml": {
    "@version": "1.0",
    "@standalone": "no"
  },
  "!DOCTYPE": {
    "@name": "notes",
    "@internalSubset": "
        <!ENTITY ent 'Sample text'>
    "
  },
  "notes": {
    "note": "Sample text"
  }
}

以上是关于Json.NET中的XML实体的主要内容,如果未能解决你的问题,请参考以下文章

需要示例代码片段帮助

.NET 中的 LINQ to JSON

条件片段和导航重用

使用 Json.Net 转换为 XML 时如何序列化空数组

错误 3002:映射片段中的问题 | c# linq 到实体

片段中的按钮自定义视图