添加命名空间uri的Xml文档,是否可以将dtd作为本地文件而不是Web验证?

时间:2012-10-17 22:40:54

标签: c# xml windows-services xml-namespaces

好吧,我对使用xml,xpath等很新。

我正在编写一个将从队列中获取信息的Windows服务。它将处理此信息,并且此信息的部分处理是在我创建的xmldocument上使用xpath而不是加载。

代码段。 :

XmlDocument _xmlDocument = new XmlDocument();
_xmlDocument.Load(svgFile);
_xmlNamespaceManager = new XmlNamespaceManager(_xmlDocument.NameTable);
_xmlNamespaceManager.AddNamespace("svg", "http://www.w3.org/2000/svg");

在上面的代码片段之后,我正在做一些xpath功能,我需要使用它,因为有一些预先编写的函数可以节省我很多时间。

这是真正的问题,当我使用上面的AddNamespace时,它会转向那个uri并占用太多时间(验证等)。我的想法是,如果我可以下载DTD并创建一个本地文件,它将节省浪费时间到网上的时间。不幸的是,没有AddNamespace xpath将无法正常工作。

我已经在网上研究过这个问题,并且无法找到解决方案。 xml是在内部创建的,所以我现在并不担心从Web上获得最新的模式。我更担心及时从服务中生成数据。也许我完全错了,这是不可能的,但从编程上讲,我不知道以前怎么做过。

2 个答案:

答案 0 :(得分:0)

使用本地文件应该可以正常工作:

  

注意:解析器不使用命名空间URI来查找   信息。

     

目的是为命名空间指定唯一的名称。但是,经常   公司使用命名空间作为指向包含的网页的指针   命名空间信息。

自: About Xml namespaces

答案 1 :(得分:0)

我最终必须创建自己的xmlresolver类,然后在本地下载dtd和一堆与之关联的mod文件。然后,而不是执行xmldocument.load,您执行类似下面的操作。 :

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ValidationType = ValidationType.DTD;
            settings.ProhibitDtd = false;
            settings.XmlResolver = new MyCoolResolver();
            binDirectory = binDirectory + "/content";
            string myFileLocation = binDirectory + "/MyFile.svg";

            using (XmlReader reader = XmlReader.Create(myFileLocation , settings))
            {
                try
                {
                    while (reader.Read())
                    {
                        _xmlDocument.Load(reader);
                    }
                }
                catch (XmlException e)
                {
                    Console.WriteLine(e.Message);
                }
            }

然后你的myxmlResolver类就是这样的。

namespace ReallyCoolProject
{
    public class MyCoolResolver : XmlUrlResolver
    {
         public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
         {
            string binDirectory =               Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
            binDirectory = binDirectory + "/mods";

            if (absoluteUri.OriginalString.Contains("-//W3C//DTD SVG 1.1//EN"))
            {
                return File.Open(binDirectory + "/svg11.dtd", FileMode.Open);
            }

            if (absoluteUri.OriginalString.Contains("-//W3C//ENTITIES SVG 1.1 Document Model//EN"))
            {
                return File.Open(binDirectory + "/svg11-model.mod", FileMode.Open);
        }

        //.....many many more mod files than this

     }
    }
}

* *个人笔记不能得到所有的功劳,因为我从网上的一堆例子中汲取了点点滴滴。