.NET:验证/读取XML架构时阻止Web访问?

时间:2011-04-13 19:07:37

标签: c# .net xml xsd xml-validation

我正在尝试阻止.NET Framework在使用XML模式验证XML文档时访问Web,因为我不希望它始终依赖于Web访问。为此,我故意创建了我在验证时使用的所有XSD的本地硬盘副本,但在加载这些模式时仍然失败。

例如,这段代码失败了(但只有从网络上拔掉我的机器):

using (Stream schemaStream = File.OpenRead(schemaFileName))
{
    XmlSchema schema = XmlSchema.Read(schemaStream, ValidationCallBack);
    xmlSchemaSet.Add(schema);
}

schemaFileName指向本地存储的xmldsig-core-schema.xsd文件副本。我得到的例外是

System.Net.WebException: The remote name could not be resolved: 'www.w3.org'
Status: NameResolutionFailure
at System.Net.HttpWebRequest.GetResponse()
at System.Xml.XmlDownloadManager.GetNonFileStream(Uri uri, ICredentials credentials)
at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials)
at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
at System.Xml.XmlTextReaderImpl.OpenStream(Uri uri)
at System.Xml.XmlTextReaderImpl.DtdParserProxy_PushExternalSubset(String systemId, String publicId)
at System.Xml.XmlTextReaderImpl.DtdParserProxy.System.Xml.IDtdParserAdapter.PushExternalSubset(String systemId, String publicId)
at System.Xml.DtdParser.ParseExternalSubset()
at System.Xml.DtdParser.ParseInDocumentDtd(Boolean saveInternalSubset)
at System.Xml.DtdParser.Parse(Boolean saveInternalSubset)
at System.Xml.XmlTextReaderImpl.DtdParserProxy.Parse(Boolean saveInternalSubset)
at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlTextReader.Read()
at System.Xml.Schema.Parser.StartParsing(XmlReader reader, String targetNamespace)
at System.Xml.Schema.Parser.Parse(XmlReader reader, String targetNamespace)
at System.Xml.Schema.XmlSchema.Read(XmlReader reader, ValidationEventHandler validationEventHandler)
at System.Xml.Schema.XmlSchema.Read(Stream stream, ValidationEventHandler validationEventHandler)

我怀疑它仍在尝试从www.w3.org加载某些东西,可能是DTD架构http://www.w3.org/2001/XMLSchema.dtd有什么方法可以阻止这种情况吗?

1 个答案:

答案 0 :(得分:3)

事实证明它比我想象的要简单。这Q/A给了我领导(并刷新了我的记忆)。

我已经拥有自己的XmlResolver实现,用于重新路由到我的本地XSD文件副本,但现在我还需要在加载XML模式时将它用于DTD:

using (Stream schemaStream = File.OpenRead(schemaFileName))
{
    XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
    xmlReaderSettings.XmlResolver = myXmlNamespaceResolver;
    xmlReaderSettings.ProhibitDtd = false;

    using (XmlReader reader = XmlReader.Create(schemaStream, xmlReaderSettings))
    {
        XmlSchema schema = XmlSchema.Read(reader, ValidationCallBack);
        xmlSchemaSet.Add(schema);                    
    }
 }

然后我需要下载http://www.w3.org/2001/XMLSchema.dtdhttp://www.w3.org/2001/datatypes.dtd的副本,现在即使没有网络访问也能正常运行。