我有一个非常古老的XML文档,它以这个开头:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE mydoc [
<!ENTITY reg "®">
<!ENTITY micro "µ">
<!ENTITY times "×">
<!ENTITY Agrave "À" ><!-- capital A, grave accent -->
<!ENTITY Aacute "Á" ><!-- capital A, acute accent -->
<!ENTITY Acirc "Â" ><!-- capital A, circumflex accent -->
<!ENTITY Atilde "Ã" ><!-- capital A, tilde -->
<!ENTITY Auml "Ä" ><!-- capital A, dieresis or umlaut mark -->
<!ENTITY Aring "Å" ><!-- capital A, ring -->
<!ENTITY AElig "Æ" ><!-- capital AE diphthong (ligature) -->
<!ENTITY Ccedil "Ç" ><!-- capital C, cedilla -->
...
<!ENTITY uuml "ü" ><!-- small u, dieresis or umlaut mark -->
<!ENTITY yacute "ý" ><!-- small y, acute accent -->
<!ENTITY thorn "þ" ><!-- small thorn, Icelandic -->
<!ENTITY yuml "ÿ" ><!-- small y, dieresis or umlaut mark -->
]>
<mydoc>
...
然后,在整个文档中,有如下行:
<someelement>Text with ä or something</someelement>
我想用 C# 反序列化它。我使用xsd.exe
生成了一个 .xsd,并使用它来自动生成 C# 类。我的反序列化代码很简单。
var serializer = new XmlSerializer(typeof(mydoc));
mydoc myDoc;
using (var fileStream = new FileStream(Path, FileMode.Open))
{
myDoc = serializer.Deserialize(fileStream) as mydoc;
if (myDoc == null)
{
throw new InvalidOperationException("Deserialization failed.");
}
}
反序列化成功,但当您检查反序列化someelement
其Value
将是:
" or something"
我检查了包含特殊实体的其他行,它们都在最后一个特殊实体处被切断,就像这样。如何强制XmlSerializer
将该行另存为
"Text with ä or something"
额外的问题:这个文件的大小只有几张,所以我想避免制作不必要的副本,我不能只是将整个文件加载到内存中并在将其传递给序列化程序之前对其进行操作。
我认为这是因为默认情况下禁用了DTD处理。
请尝试以下代码:
var settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
using (var xmlReader = XmlReader.Create(Path, settings))
{
myDoc = serializer.Deserialize(xmlReader) as mydoc;