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?

1 Answer 1

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"
  }
}
Sign up to request clarification or add additional context in comments.

6 Comments

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?
You mean, with entities, or with entity references? entity references are definitely not supported, logic for them simply doesn't appear in XmlNodeConverter.cs. If entities, I'm not sure. Can you ask another question with a minimal reproducible example?
@andrzej1_1 - XmlTextReader is deprecated so updated answer to use XmlReader.Create(textReader, settings)
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 - you could request an enhancement to XmlNodeConverter.cs to support them at github.com/JamesNK/Newtonsoft.Json/issues.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.