1

次の XML ドキュメントがあるとします。

<foo>
  <bar/>
  <bang bash="hello">
    <foobar>123</foobar>
  </bang>
</foo>

たとえば、このドキュメントのさまざまなリーフへのすべてのパスのリストを抽出したいと思います。

foo
foo.bar
foo.bang
foo.bang.@bash
foo.bang.foobar

このプロセスに用語はありますか?

さらに一歩進んで、非常に複雑な XML スキーマの .xsd があるとします。.xsd からそのようなパスをすべて抽出する簡単な方法はありますか?

(簡単に言えば、理想的には、これを行うためのライブラリがどこかに存在するということですか?)

4

3 に答える 3

2

SGML コミュニティでは、探している値は (要素が含まれる場合) 「完全修飾汎用識別子」または FQGI と呼ばれていました。なぜなら '。' は XML および SGML リファレンスの具体的な構文で有効な名前文字です。FQGI は通常、ドットを書く場所にスラッシュを付けて書かれます。(ここでは FQGI という用語を拡張し、要素ではなく属性を表す文字列を含め、関心のある文字列を表すために使用します。)

特定のスキーマに対して有効なドキュメントに表示される可能性のあるすべての FQGI のセットを見つけるプロセスに対して確立された用語を知りません。多くの XML ボキャブラリーでは、これは無限集合であることに注意してください。終了するプロセスが必要な場合は、可能なすべての FQGI の有限サブセットを特定する必要があります。

ただし、従う必要があるプロセスは比較的単純です。単純なバージョンは次のように実行されます。

  1. 関心のあるスキーマが複数のスキーマ ドキュメントにわたって定義されている場合は、それらをすべて 1 つの XML ドキュメント (複数の xs:schema 子を持つラッパー) または XSLT または XQuery を使用して処理できるスキーマ ドキュメントの 1 つのコレクションにまとめます。

  2. 開始したい要素宣言と属性宣言のセットを特定します。(あなたの場合、このセットはおそらく foo の最上位の要素宣言で構成されています。) このセットの各項目について、その名前と型を書き留めます。この文字列と型のペアのセットを S と呼びます。

  3. 集合 S を集合 S' にコピーします。

  4. セット S'' を次の方法で作成します。空の S'' で開始し、S' 内の各アイテムについて、N を FQGI とし、T をアイテムで指定された型とし、次のようにします。

    (a) N が属性を表す場合、何もしません。

    (b) N が要素を表す場合、そのような要素に表示される属性のセットを特定します。そのような属性ごとに、そのタイプ T2 を識別し、N、スラッシュ、アットマーク、および属性の拡張名を連結して文字列 N2 を作成します。ペア (N2、T2) を S'' に追加します。

    (c) N が要素を表す場合、(i) T のコンテンツ モデルに現れる、(ii) T のコンテンツ モデルのワイルドカードに一致する、または (iii) で指定された要素に置換可能な要素のセットを見つけます。 (i) または (ii)。そのような可能な子ごとに、子のタイプ T3 を識別し、N、「/」、および可能な子の拡張名を連結して文字列 N3 を作成します。ペア (N3、T3) を S'' に追加します。

  5. S'' が空の場合、答えは集合 S と集合 S' の和集合にあります。そうでない場合、(新しい) S を S と S' の結合とし、(新しい) S' を S'' と等しくし、ステップ 4 に進みます。

少し考えると、ワイルドカードに一致する名前のセットは無限にあることがわかります。そのため、ステップ 4(c) のリスト (ii) は完全には処理できません。リストの有限サブセットをさまざまな方法で選択できます。どちらを選択するかは、FQGI のリストが何のために必要かによって異なります。

もう少し考えてみると、ボキャブラリ内の要素が独自の子孫として表示される場合 (HTML の div 要素や li 要素など)、概説されているプロセスは決して終了しないことがわかります。繰り返しになりますが、4(c) で生成されたペアのセットをトリミングして終了を保証するさまざまな方法があります。

これを行うライブラリを私は知りません。おそらく、可能な FQGI のセットが、興味深い XML ボキャブラリに対して有限であることがめったにないためです。XQuery エンジンまたは XSLT スタイルシートで作業を行うのは簡単です。

于 2013-03-05T19:25:10.043 に答える
1

同様の質問がSOに投稿されました。関連する投稿で説明したものを除いて、シナリオのすぐに使用できるソリューション(APIまたはその他)をまだ認識していません。

私は、 SOについて説明したソリューションでさえ、特定のXSD機能をカバーしていないか、特定のXPathの生成方法に関する特定の期待と一致しない可能性があることを最初に認識しました。パターンに一致するカスタム式を使用して計算列を追加できるため、更新されたリクエストからのものをサポートできます(XPathによって一致するノードのタイプなどの追加の「メタデータ」を含めるため)。

CM Sperberg-McQueenによって記述されたアルゴリズムは、それが含む可能性のあるいくつかのことについてのアイデアを確実に提供しますが、単純なアプローチに関する穏やかな「免責事項」によって構成されています。 XSD仕様は省略されました。

XSDが本当に単純でない限り、ティーザーを検討してください。いくつかの「悪い」例:複雑な型(要素参照だけでなく)を介した再帰的なXML構造(ほのめかされている)は注意が必要です。XSDの設計で型階層が重くて普及している場合はさらに注意が必要です。抽象型要素の使用(インスタンスXMLのxsi:type属性を考えてください)、ブロック属性の使用、フォーム属性、カメレオンXSDの使用(異なるデフォルトが使用されているかどうかは言うまでもなく、ステップ1はそれ自体ですべて楽しいですスキーマレベルの要素/属性フォームの場合)。

これらの追加の「詳細」の一部がXSDに適用できる場合は、XQueryまたはXSLTを忘れて、専用のスキーマオブジェクトモデルAPI(Java上のXSOM、.NETにも非常に優れたものがあります)を使用することをお勧めします。 XSDをトラバースします-ここで、@ pgfearoが言ったことをひねりを加えて繰り返しました(私が知っていることから、SAXON XSDサポートは有料版でのみ利用可能ですが、ApacheとJAXB RIは無料でXSOMを提供します)。そうすれば、多くのことを心配する必要はなく、おそらく妥当な時間でそれを行うことができるでしょう。

于 2013-03-06T03:34:18.063 に答える