11

任意のXMLファイルが特定のスキーマと一致するかどうかを(trueまたはfalseで)テストしたいと思います。

価値のあるものとして、スキーマはWord 2003 WordMLスキーマであり、Microsoftは約7つの*.xsdファイルのリストを使用して定義しています。

xml.xsdこれらのファイルの1つには、次のステートメントを含めることにより、W3Cファイルも含まれています。

<xsd:import id="xml" namespace="http://www.w3.org/XML/1998/namespace"
    schemaLocation="http://www.w3.org/2001/xml.xsd"></xsd:import>

検証を行うために、次のような.NETコードを使用しています。

   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 Files\Microsoft Office 2003 Developer Resources\Microsoft Office 2003 XML Reference Schemas\WordprocessingML Schemas\wordnet.xsd"
           );
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationEventHandler += new ValidationEventHandler(validationEventHandler);
        XmlReader xmlReader = XmlReader.Create(filename, settings);
        while (xmlReader.Read()) { }
   }

私の問題は、インターネットに接続されていないマシンでこのコードを実行すると、XmlSchemaValidationException見つからないというエラーが発生することxml.xsdです。

これを修正するために、xml.xsdのコピーをダウンロードし、settings.Schemas.Addメソッドを使用して明示的に追加しました。マシンがインターネットに接続されていない場合でも、検証が正しく機能するようになりました。

ただし、マシンがインターネットに接続されていると、次のようなエラーが発生しThe global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared.ます。

したがって、マシンがインターネットからサイレントにダウンロードできるかどうか(または以前にダウンロードできてどこかにキャッシュされているかどうか)に応じて、明示的に追加する必要があるか、追加しないようです。

ですから、それは「私がそうするなら、そして私がそうしないなら、くそったれ」です。ある方法で試して、例外をキャッチしてから、別の方法で試す必要がありますか?または、よりエレガントなソリューションはありますか?

4

1 に答える 1

4

コードを確認できませんが、多くの実装では、カタログリゾルバーを使用して.xsdのリクエストをローカルコピーにリダイレクトすることでこれを処理します。これに使用できるプロパティXmlReaderSettings.XmlResolverがあります。使用できるApacheライセンスの実装については、XMLCatalog.netを参照してください。

これの副作用は、すべてのスキーマをローカルにキャッシュしておくことができることです。W3Cはサイトへの過度の読み取りをブロックし、ランダムにコード(またはさらに悪いことに顧客のコード)が失敗し始めるため、これは特に重要です。

于 2010-08-17T03:21:54.447 に答える