1

Json.NET support converting JSON to and from XML. So I tried simple code like this:

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

As a result there is thrown exception:

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

I can't find any information about (non)supporting entities, so maybe I am doing something wrong?

andrzej1_1
  • 1,151
  • 3
  • 21
  • 38

1 Answers1

1

The exception is explanatory: Json.NET apparently hasn't implemented conversion of XmlEntityReference nodes to JSON. This is the XmlNode subtype that is used to represent the &ent; entity reference.

To avoid the limitation you will need to expand entities while reading your XML, for instance like so:

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

Notes:

Or you could switch to the XDocument API in which entities are always expanded and security settings are more appropriate by default:

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

Working .Net fiddle showing that the &ent; node gets expanded to its value Sample text:

{
  "?xml": {
    "@version": "1.0",
    "@standalone": "no"
  },
  "!DOCTYPE": {
    "@name": "notes",
    "@internalSubset": "\n        <!ENTITY ent 'Sample text'>\n    "
  },
  "notes": {
    "note": "Sample text"
  }
}
dbc
  • 104,963
  • 20
  • 228
  • 340
  • Whoa, thank you for great fiddle! This solve my problem, but I am also wondering, whether it is possible to deserialize these JSONs to initial XML with entities? – andrzej1_1 Dec 19 '17 at 09:24
  • 1
    You mean, with entities, or with entity **references**? entity references are definitely not supported, logic for them simply doesn't appear in [`XmlNodeConverter.cs`](https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs). If entities, I'm not sure. Can you ask another question with a [mcve]? – dbc Dec 19 '17 at 09:41
  • 1
    @andrzej1_1 - XmlTextReader is deprecated so updated answer to use XmlReader.Create(textReader, settings) – dbc Dec 19 '17 at 17:14
  • I mean entity references, so there is no need to ask another question if you said they are not supported. And thanks for update. – andrzej1_1 Dec 19 '17 at 20:21
  • @andrzej1_1 - you could request an enhancement to `XmlNodeConverter.cs` to support them at https://github.com/JamesNK/Newtonsoft.Json/issues. – dbc Dec 19 '17 at 20:22
  • It's not necessary for me, I was just curious if they are supported. – andrzej1_1 Dec 19 '17 at 20:24