問題描述
我想測試(真或假)任意 XML 文件是否與給定架構匹配.
I want to test (true or false) whether an arbitrary XML file matches a given schema.
值得一提的是,該架構是 Word 2003 WordML 架構,Microsoft 使用大約 7 個 *.xsd
文件的列表來定義它.
For what it's worth, the schema is the Word 2003 WordML schema, which Microsoft defines using a list of about 7 *.xsd
files.
其中一個文件還包括 W3C xml.xsd
文件,包括以下語句:
One of these files also includes the W3C xml.xsd
file, by including the following statement:
<xsd:import id="xml" namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/xml.xsd"></xsd:import>
我正在使用如下所示的 .NET 代碼進行驗證:
I am using .NET code like the following to do the validation:
public static void validate(string filename)
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(
"http://schemas.microsoft.com/office/word/2003/wordml",
//to get this file I downloaded "Office 2003: XML Reference Schemas", i.e. "Office2003XMLSchema.exe"
@"C:Program FilesMicrosoft Office 2003 Developer ResourcesMicrosoft Office 2003 XML Reference SchemasWordprocessingML Schemaswordnet.xsd"
);
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += new ValidationEventHandler(validationEventHandler);
XmlReader xmlReader = XmlReader.Create(filename, settings);
while (xmlReader.Read()) { }
}
我的問題是,如果我在未連接到 Internet 的機器上運行此代碼,則會收到 XmlSchemaValidationException
錯誤,大意是找不到 xml.xsd
.
My problem is that if I run this code on a machine which is not connected to the internet, then I get a XmlSchemaValidationException
error to the effect that it can't find xml.xsd
.
為了解決這個問題,我下載了 xml.xsd 的副本,并使用 settings.Schemas.Add
方法顯式添加:當機器未連接到 Internet 時,驗證現在可以正常工作.
To fix this, I downloaded a copy of xml.xsd, and add it explicitly using the settings.Schemas.Add
method: the validation now works correctly when the machine is not connected to the internet.
但是,當機器連接到 Internet 時,我現在收到一條錯誤消息,指出 全局屬性 'http://www.w3.org/XML/1998/namespace:lang' 已被聲明.
.
However when the machine is connected to the internet, I now get an error saying that The global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared.
.
所以顯然我需要明確添加它,或者我不需要,這取決于機器是否能夠從互聯網上靜默下載它(或者甚至可能以前能夠下載它,并將它緩存在某個地方).
So apparently I either need to add it explicitly, or I don't, depending on whether the machine is able to silently download it from the internet (or even perhaps has previously been able to download it, and has it cached somewhere).
所以,它是如果我這樣做該死,如果我不這樣做該死".我是否需要以一種方式嘗試,捕獲異常,然后以另一種方式嘗試?還是有更優雅的解決方案?
So, it's "damned if I do and damned if I don't". Do I need to try it one way, catch the exception and then try it the other way? Or is there a more elegant solution?
推薦答案
我們看不到您的代碼,但是在許多實現中,這是通過將 .xsd 的請求重定向到本地來處理的使用目錄解析器進行復制.有一個屬性 XmlReaderSettings.XmlResolver可用于此.請參閱 XMLCatalog.net 了解您可以使用的 Apache 許可實現.
We can't see your code, but In many implementations this is handled by redirecting the request for the .xsd to the local copy using a catalog resolver. There is a property XmlReaderSettings.XmlResolver that can be used for this. See XMLCatalog.net for an Apache-licensed implementation you can use.
這樣做的副作用是您可以將所有模式緩存在本地.這一點尤其重要,因為 W3C 會阻止對其站點的過度讀取,并且您的代碼(或更糟糕的是,您客戶的代碼)會隨機開始失敗.
A side-effect of this is that you can keep all schemas cached locally. This is especially important since W3C will block excessive reads to their site and randomly your code (or worse, your customer's code) will begin to fail.
這篇關于使用 .NET 針對架構驗證 XML的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!