2

循環依存関係を持つ 2 つのスキーマ A と B があります (これは中間ステップです)。入力として使用している XML ファイルは、xmllint と Visual Studio に従ってスキーマに対して検証されます。Eclipse から、両方のスキーマに同じ名前の 2 つのグローバル コンポーネントが含まれていることがわかります。

A.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance"
  targetNamespace="http://foo.org/A"
  xmlns="http://foo.org/A"
  elementFormDefault="unqualified"
  attributeFormDefault="unqualified">

<xs:import schemaLocation="b.xsd" />

B.xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance"
  xmlns:foo="http://foo.org/A"
  elementFormDefault="unqualified"
  attributeFormDefault="unqualified">

  <xs:import namespace="http://foo.org/A" schemaLocation="a.xsd" />

Unmarshaller に渡す XSD は A.xsd です。B.xsd で定義された要素に遭遇すると、次のように文句を言います。

org.xml.sax.SAXParseException: cvc-elt.1: 要素「foo」の宣言が見つかりません。

(疑似)経由でスキーマを設定しました:

InputStream in = .. A.xsd
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
return factory.newSchema(new StreamSource(in);

誰かが私が間違っていることを説明できますか? ありがとう。

4

1 に答える 1

1

<xs:import>他のスキーマで定義された名前空間を現在のスキーマにインポートするために使用されます。このschemaLocation属性は、他の名前空間がどこにあるかを示すヒントにすぎません。

の場合B.xsd、名前空間をインポートしたいということhttp://blah.orgであり、その名前空間は のスキーマによって処理されますA.xsd

の場合A.xsd、 のインポートでB.xsdは、インポートする名前空間が指定されていません。

A.xsdB.xsdが異なる名前空間を表している場合、 はそれimportを明示的に指定する必要があります。

一方、同じ名前空間内の別のスキーマ ファイルから要素をインライン化しようとしているだけの場合は、includeディレクティブがより適切です。


編集: OK、スキーマの断片を見たので、それ<xs:import>は間違いなく正しいことではないと言えます。A.xsdとはどちらもB.xsd同じ名前空間 ( ) で要素を定義しているhttp://foo.org/Aため、代わりに を使用する必要があります<xs:include>

Java が , に遭遇し<xs:import>、そのインポートの名前空間が既に認識されている名前空間である場合、Java は事実上それを無視します。したがって、B.xsd( namespace でhttp://foo.org/A)解析していて、同じ名前空間のインポートが見つかった場合、それは無視されます。

于 2010-02-12T14:27:18.717 に答える