繁体   English   中英

使用外部实体文件在C#中处理XML

[英]Process XML in C# using external entity file

我在C#中处理一个包含é等实体的XML文件(不包含任何dtdent声明) é à 尝试加载XML文件时收到以下异常...

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(record);

提及未申报实体'eacute'。

我能够追踪正确的ENT文件在这里 如何在加载XML文件时告诉XmlDocument使用此ent文件?

在.Net 4之前的框架版本中,您使用XmlReaderSettings实例的ProhibitDtd

var settings = new XmlReaderSettings();

settings.ProhibitDtd = false;

string DTD = @"<!DOCTYPE doc [
    <!ENTITY % iso-lat1 PUBLIC ""ISO 8879:1986//ENTITIES Added Latin 1//EN//XML""
    ""http://www.oasis-open.org/docbook/xmlcharent/0.3/iso-lat1.ent"">
    %iso-lat1;
    ]> ";

string xml = string.Concat(DTD,"<xml><txt>ren&eacute;</txt></xml>");

XmlDocument xd = new XmlDocument();
xd.Load(XmlReader.Create(new MemoryStream(
        UTF8Encoding.UTF8.GetBytes(xml)), settings));

从.Net 4.0开始,使用DtdProcessing属性,其值为DtdProcessing.Parse ,您在XmlTextReader上设置该值。

XmlDocument xd = new XmlDocument();
using (var rdr = new XmlTextReader(new StringReader(xml)))
{
    rdr.DtdProcessing = DtdProcessing.Parse;
    xd.Load(rdr);
}     

我遇到了同样的问题,并且不想修改我的XML(或DTD),我决定创建自己的XmlResolver来动态添加实体。

我的实现实际上从配置文件中读取实体,但这应该足以满足您的要求。 在这个例子中,我正在将一个正确的单个卷曲引号转换为撇号。

class XmlEntityResolver : XmlResolver {
    public override object GetEntity(Uri absoluteUri,
                                     string role,
                                     Type ofObjectToReturn) 
    {
        if (absoluteUri.toString() == "-//MY PUB ID") {
            MemoryStream ms = new MemoryStream();
            StreamWriter sw = new StreamWriter(ms);
            sw.Write("<!ENTITY rsquo \"'\">");
            sw.Flush();
            ms.Position = 0;
            return ms;
        }
        else {
            return base.GetEntity(absoluteUri, role, ofObjectToReturn);
        }
    }
}

然后,当您声明XmlDocument时,只需在加载之前设置解析器。

XmlDocument doc = new XmlDocument();
doc.XmlResolver = new XmlEntityResolver();
doc.Load(XML_FILE);

&eacute; 默认情况下,它不是有效的XML实体,而默认情况下它是有效的HTML实体。

你需要定义&eacute; 作为XML解析目的的有效XML实体。

编辑:

要添加对外部文件的引用,您需要在XML文件本身中执行此操作。 将ent文件保存到磁盘并将其放在与正在分析的文档相同的目录中。

<!ENTITY % stuff SYSTEM "iso-lat1.ent">
%stuff;

如果您想要使用其他路线,请查看有关ENTITY声明的信息。

您的问题已于2004年在MSDN文章中得到解答........您可以在这里找到它......

http://msdn.microsoft.com/en-us/library/aa302289.aspx

根据这个 ,你必须在文件中引用它们; 你无法告诉LoadXml为你做这件事。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM