私は不可能かもしれない何かをしようとしています。
同じタイプのレコードのリストを含む 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
Node
custom の内部に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)
は、少なくとも私にとっては正しい答えでした。それで、ペトルは切望された緑色のチェックマークを取得します.