2

XSD ファイルに対して XML ファイル (XML ファイルに名前空間もスキーマ宣言もありません) を検証したいと考えています。

XML ファイルは次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<report> ... </report>

XSD ファイルは次のとおりです。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="report">
    ...
  </xs:element>
</xs:schema>

コードは次のようになります。

SchemaFactory xsdFac = SchemaFactory.newInstance(
   XMLConstants.W3C_XML_SCHEMA_NS_URI);
xsdFac.setErrorHandler( ... );
Schema xsd = xsdFac.newSchema(xsdUrl);  // xsdUrl works
Validator xsdValidator = xsd.newValidator();
xsdValidator.validate(new DOMSource(doc));  // doc is correct

私はこれに 3 時間を費やしました。PC でローカルに動作し、以前はサーバーで動作していた (と思います) が、現在はサーバーでは動作しません。PC とサーバーの違いを特定しようとしましたが、どちらも同じ JAR を使用しているなどです。

とにかく、私は次の違いを特定しました。クラス名をメソッドに渡していませんでしたSchemaFactory.newInstance(ほぼ間違いなく間違いです)。 のクラス名を出力するxsdFacと、ローカルとサーバーで異なることがわかりました。なぜそうなったのかを知りたいとは思いません(私にはわかりません)。機能するものを見つけて、明示的に指定する方がよいと思います。

  • 私のPC(動作)ではそうでしたcom.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactorynewInstance呼び出しで明示的に指定すると、PC とサーバーで動作します。
  • サーバー上 (動作しませんでした) でしたorg.apache.xerces.jaxp.validation.XMLSchemaFactorynewInstance呼び出しで明示的に設定すると、PC とサーバーの両方で同じエラーが発生します。

com.sun動作するものの先頭にあることに注意してください。

だから少なくとも私は解決策を持っています、それは良いことです。com.sunしかし、コードで明示的にクラスを使用するべきではないと思いますか?

その他の情報:

  • 私が得るエラーは次のとおりです。org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'report'
  • これは、動作中のバージョンで、要素名をスキーマに存在しない別のものに変更したときに発生するエラーと同じです。つまり、「私はあなたのスキーマを理解しており、XML を理解しています。そして、スキーマのどこにも宣言されていない要素を使用しています」という意味だと思います。
  • xercesImpl-2.9.1.jar私のプロジェクトにあります(サーバーとPCの両方)。
  • この JAR にはXMLSchemaFactory.class、非動作バージョンで指定されたパッケージの下に含まれています (つまり、そこにあり、検出可能であり、動作するはずであり、結局、見つからないクラスに関連する例外は発生しません)。
  • doc私が解析しているオブジェクトは、どちらの場合も、org.apache.xerces.dom.DeferredDocumentImpl

したがって、私の質問は次のとおりです。スキーマファクトリの明示的な Xerces 実装を使用したいと思います (と思います)。JAR を含め、Xerces の Document オブジェクトがあり、基本的に Xerces バリデーターを使用しています (動作ケースcom.sun)。

似たような経験をした人はいますか?

4

1 に答える 1

2

実際、失敗した場合、クラスパスに Xerces がないと推測できます。

-Djaxp.debug は、呼び出している JAXP API を呼び出すときに、どの実装がアクティブであるかを確実に通知します。

これがそうであり、それが単にクラスパスの間違いの結果ではない場合、JAXP ジェネリック ファクトリ メソッドを呼び出す代わりに、Xerces クラスを具体的に「新規」にすることができます。やりました。

編集

コメントは、これが webapp であることを示しています。JAXP クラスは、クラスのロード規則を考えると、Web アプリケーションに配置するのが難しいものの 1 つです。少なくとも、Tomcat の「システム」クラスパスに入れてみて、何が起こるかを確認してください。

于 2011-02-19T23:37:36.847 に答える