2017-12-19 2 views
1

JSONをXMLとの間で変換するJson.NETのサポート。ので、多分私は何かをやっている、私は(非)サポートエンティティについての情報を見つけることができませんJson.NETのXMLエンティティ

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

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

例外がスローされる結果:だから私はこのような簡単なコードを試してみました違う?

答えて

1

例外は説明しています.Json.NETは明らかにXmlEntityReferenceノードのJSONへの変換を実装していません。これは&ent;entity referenceを表すのに使用されるXmlNodeサブタイプです。あなたがそうのように、たとえば、あなたの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); 

注:

  • それは実行するために信頼されていないXMLファイルのことが可能ですhereのように、巧妙に細工されたDTDエンティティとエンティティ参照を使用してメモリ不足の例外を強制することによりサービス拒否攻撃を受けます。 XmlReaderSettings.MaxCharactersFromEntitiesを妥当な値に設定すると、それが軽減されます。

    この具体的な値は、reference source for XDocument.Load()から取得しました。ニーズに合わせて変更します。

  • 同様に設定するとXmlReaderSettings.XmlResolver = nullは、信頼できないXMLが外部リソースへの予期しない要求を生成するのを防ぎます。

それとも、エンティティが常に展開され、セキュリティ設定は、デフォルトでは、より適切である、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": "\n  <!ENTITY ent 'Sample text'>\n " 
    }, 
    "notes": { 
    "note": "Sample text" 
    } 
} 
+0

偉大なフィドルのためにありがとう!これは私の問題を解決しますが、これらのJSONをエンティティで初期XMLにデシリアライズすることが可能かどうかも疑問です。 –

+1

実体、または実体**参照**を意味しますか?エンティティ参照はサポートされていませんが、それらのロジックは['XmlNodeConverter.cs']には表示されません(https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/ XmlNodeConverter.cs)。エンティティの場合は、わかりません。あなたは[mcve]で別の質問をすることができますか? – dbc

+1

@ andrzej1_1 - XmlTextReaderは廃止予定ですので、XmlReader.Create(textReader、settings)を使用するように更新されました。 – dbc