1

私は不可能かもしれない何かをしようとしています。

同じタイプのレコードのリストを含む XML ドキュメントがあります。このようなもの:

<root>
  <record>I'm a shark.</record>
  <record>I'm a shark.</record>
  <record>Suck it.</record>
  <record>I'm a shark.</record>
</root>

まず、XSD を実行して、タグが正しいことを確認します。次に、それを非整列化し、実際の値に対してプログラムによる検証を行います。この 2 番目のステップを XSD 経由で折りたたみたいと思い<xs:pattern />ます (値を正規表現と照合して有効性をテストします)。

問題は、XML ドキュメントにリストされている有効なすべてのレコードの処理を続行し、そうでない特定のレコードのみを失敗させるというビジネス ルールがあることです。上記の例では、「Suck it」を失敗させたいと考えています。すべての「私はサメです」を評価して渡します。実際の使用のためのいくつかの処理ステップへの値。

残念ながら、私の知る限り、XSD では、1 つの部分が失敗すると、ドキュメント全体が「不良」であり、検証に失敗します。したがって、上記の例では、「Suck it」です。value はドキュメント全体を削除します。これを回避する方法はありますか?プログラムによる 2 番目のステップで行き詰まっているだけですか? ドキュメント全体ではなく個々のタグのみを失敗させることができる場合、「このタグはこの理由で失敗しました」に到達する方法はありますか。検証中?

編集:セットを使用して を使用しSAXParser、XMLを手動で処理Schemaするカスタムクラスを拡張して渡しました。DefaultHandler

Nodecustom の内部にprivate class を設定しましたDefaultHandler。これは、信じられないほど単純な Tree 実装です。それぞれNodeに、開始タグ、値、および終了タグが含まれ、すべて として保存されString、さらに親と子への関係が含まれます。SAXException「cvc-pattern-valid」または「cvc-type.3.1.3」(または取得したい XML エラー) で始まるメッセージを含むメッセージを取得するたびにNode、ツリーから I'm in the middle of を削除します。私は(壊れているため)構築していて、次の段階に進みます。次に、 (さまざまな を使用する) ルートStringを呼び出して解析を完了すると、ドキュメント全体 (選別されたタグを除く) を大きな XML として出力できます。Node.depthFirstSearch()StringBuilder

私の問題は、XML を XML として扱うためだけに、途方もない量の作業を行っているように感じることです。<" "、" >"、および " " の文字を再度追加する必要が<\あります。これは、 のメソッドでDefaultHandlerは stripped のようなものしか得られないためですqName。そして、このツリーの構築とトラバースはすべて非効率的です。仕事が多すぎるように。確かにもっと簡単な方法があるはずですか?

注: XML を XML のままにしておく理由は、これが私の以前のワークフローだったからです。

XSD -> XSLT -> Unmarshal to JAXB-Annotated Object

これは次のとおりです。

SAXParser(XSD) -> XSLT -> Unmarshal to JAXB-Annotated Object

魔法のような方法があるかもしれません:

SAXParser(XSD, XSLT) -> Unmarshal to JAXB-Annotated Object

または

SAXParser(XSD, XSLT, Unmarshal to JAXB-Annotated Object)

しかし、それがどうなるかはわかりません。

編集:まあ、可能性のある非効率性はさておき、拡張DefaultHandler、オーバーライドDefaultHandler.error(SAXParseException exception)は、少なくとも私にとっては正しい答えでした。それで、ペトルは切望された緑色のチェックマークを取得します.

4

3 に答える 3

1

JAXB にはカスタム エラー ハンドラを設定する機能があるため、すべての処理を放棄するというデフォルトの動作をオーバーライドできます。特定のテスト ケースで試してみて、どのように機能するかを確認してください。

私の知る限り、すべての主要なバリデーターには、処理を続行できるようにする目的で、検証エラーのカスタム処理を許可するイベントベースのアプローチがあります。

最悪のシナリオは、JAXB を直接ではなく、SAX API などを使用して XML を実際に解析することです。これにより、エラー処理をより適切に制御できる場合があります。次に、recordノードが正常に検証され、JAVA クラスにアンマーシャリングされます (ただし、二重解析になります)。

于 2013-03-07T21:08:17.030 に答える
0

Saxon は、Michael Sperberg-McQueen が説明する理想化された XSD プロセッサには達していません。これは主に、XSD 仕様に組み込まれているすべての柔軟性を必要としないスキーマ認識 XSLT および XQuery 処理のニーズに合わせて設計されているためです。ただし、完全な PSVI は実際には必要ないため、まだ長い道のりを歩むことができます。必要なのは、ソース ドキュメントとエラーのリスト [私の用語であり、XSD 仕様で使用されている用語ではありません] であり、.何らかの方法で。そして、それは十分に簡単に実現できます。詳細は、ツリー ベースまたはイベント ベースのどちらの処理アプローチが必要かによって異なります。

(同じことが他の XSD プロセッサにもほぼ確実に当てはまりますが、私が最もよく知っているのは Saxon です)。

処理オプションを正しく選択すると、Saxon は常に検証エラーの後も続行しますが、場合によっては、ドキュメントの一部に対してそれ以上の検証を行わないことを決定します。たとえば、コンテンツ モデルに (a,b,c,d) が含まれていると想定されていて、インスタンスに実際に (a,x,b,c,d) が含まれている場合、x でエラーが報告されると、検証は実行されません。 b、c、およびdに出ます。

于 2013-03-07T22:45:35.980 に答える
0

概念レベルと実践レベルを区別しましょう。

概念的に - XSD は、ドキュメント全体 (より具体的には、検証が開始されるドキュメント ノード) だけでなく、検証が開始されるノードをルートとするサブツリー内の各ノードに対しても有効性を定義します。

したがって、ドキュメントの PSVI (スキーマ検証後の情報セット) では、各「レコード」要素は概念的に [validity=valid] または [validity=invalid] または [validity=notKnown] でマークされます。ご覧のとおり、無効性は上方に伝播するため、親の「ルート」要素に無効な子要素がある場合、通常は無効になります。

XSD 仕様では、入力が無効であることを発見したアプリケーションが入力の処理を続行するか中止するかについては何も述べていません。これは XSD 仕様の範囲外です。有効な 'record' 要素を処理し、無効な要素で何か別の処理を行いたい場合、XSD 仕様は、そのために必要な情報をバリデーターが提供できるように設計されています。

実際には、多くのユーザーと一部の実装者は、XSD によって定義された有効性のより豊かな概念の有用性を認識していないため、多くのバリデーターとコード バインディング ツールは、デフォルトで実質的に有効性を検証ルートの単一のブール プロパティに減らす API を提供しています。一部のツールでは、この有効性の縮小された概念が、ツールが実際にサポートする唯一のものです。

したがって、バリデーターの API は、「レコード」要素の有効性情報にアクセスできる場合とできない場合があります。その場合は、消費するコードを記述して API に問い合わせ、それに応じて行動するだけです。そうでない場合は、その情報が必要であることをベンダーに伝える必要があります (または、別のバリデーターを探します)。データ バインディング ツールを使用してコードを生成する場合も、同じ原則が当てはまります。無効な入力が存在する場合でも問題なく使用できるコードをツールで生成する方法を見つけ、ツールがそれをサポートしていない場合は、ベンダーに問い合わせてください。なぜだめですか。

XSD はバリデーターの API や最低限の品質基準を定義しようとはしていないため、ベンダーに XSD の完全なネイティブの妥当性概念へのアクセスを提供するよう説得する唯一の方法は、市場からの圧力を利用することです。

XSD は、ドキュメント全体の単純なブール型プロパティとしてではなく、検証されたドキュメントの部分のすべてのノードの 3 つの値を持つプロパティ (valid、invalid、notKnown) として有効性を定義する点で、他のスキーマ言語と部分的に異なります。あなたが説明したような使用シナリオは、(コメントで Stanley de Boer によって提供されたビューとは対照的に) その作業の中心的な動機でした。したがって、現在の XSD バリデーターでやりたいことができない場合、障壁は XSD 自体ではなく、実装にあります。

幸運を。

于 2013-03-07T19:10:02.943 に答える