0

XMLファイルのテキストコンテンツ(文字データ)を一連の正規表現と照合し、照合に基づいてXMLを変更しようとしています。例:

 <text>
 <para>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
 </para>
 </text>

たとえば、次の正規表現をテキストに一致させたいと思います。

\bdolor.\b

試合ごとに、たとえば試合をタグなどで囲みたいので、上記は次のようになります。

<text>
<para>Lorem ipsum <bold>dolor<bold/> sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et <bold>dolore<bold/> magna aliqua.
</para>
</text>

さらに厄介なのは、照合したいテキスト(文字データ)が複数のタグにまたがる可能性があることです。

私がやろうとしていることは、テキストの一致する部分を選択し、たとえば一致/選択されたテキストのフォーマットを変更する検索を実行した場合に、ワードプロセッサアプリが実行する必要があることと非常に似ていると思います。

これを行うためにJava(実際にはClojure)を使用したいと思います。また、JAXBを使用してXMLドキュメントを操作する予定です。

上記を行うにはどうすればよいですか?

4

2 に答える 2

2

編集:

これでタグにまたがることができることを理解したので、ここでの難しさを理解したと思います。

ここで私が考えることができる唯一のアルゴリズムは、一致するものを検索するテキスト部分を読み取るXMLツリーを歩くことです。これは、複数のノードにわたって文字ごとに一致させる必要があります。もちろん難しいのは、その過程で木をつぶさないことです...

これが私がそれをする方法です:

XMLツリーに移動するウォーカーを作成します。文字列の一致の開始を見つけたと思うときはいつでも、現在の親ノードが何であれ保存してください。文字列の終わりが一致した場合(およびその場合)、保存されたノードが終了ノードの親と同じであるかどうかを確認します。それらが同じである場合は、ツリーを変更しても安全です。

サンプルドキュメント:

<doc>This is a an <b>example text I made up</b> on the spot! Nutty.</doc>

テスト1:一致:テキスト例

ウォーカーは、例で「e」が見つかるまで歩き、親ノード(ノード)を保存し、同じ参照ノードにあるかどうかを確認する場所<b>の終わりが見つかるまで歩き続けます。一致しているので、タグを付けることができます。text<b>

テスト2:一致:例

ウォーカーは最初にヒットaしてすぐに拒否し、次にノードをヒットanして保存し<doc>ます。例の親ノードが存在し、一致が失敗し、ノードがインストールされていないexampleことを認識するまで、テキストとの一致を継続します。<b><doc>

実装1:

ストレートテキストのみを照合する場合は、Java(SAXなど)を使用した単純なマッチャーがここに行く方法のように思われます。

実装2:

一致する入力が正規表現自体である場合は、非常に特別なものが必要になります。ここで確実に機能するエンジンがないことを私は知っています。あなたができるかもしれないことは、それを行うために少し醜い何かを書くことです...多分XMLツリーをますます小さなノードに分解するある種の再帰ウォーカー-セット、各レベルで完全なテキストを検索...

非常にラフな(機能しない)コード:

def search(raw, regex):
    tree = parseXml(raw)
    text = getText(tree)
    if match(text, regex):


def searchXML(tree, regex):
    text = getFlatText(tree)
    if match(text, regex): # check if this text node might match
        textNodes = getTextNodes(tree)
        for (tn : textNodes): # check if its contained in a single text node
            if match(tn, regex):
                return tn
        xmlnodes = getXMLNodes(tree)
        for (xn : xmlnodes): # check if any of the children contain the text
            match = searchXML(xn, regex)
            if match
                return match
        return tree # matches some combination of text/nodes at this level
                    # but not at a sublevel
    else:
        return None # no match in this subtree

一致が含まれるノードがどこにあるかがわかれば、正規表現から必要なテキスト内のインデックスを把握する方法がわからないため、何ができるかわかりません...多分誰か変更できる正規表現があります...

于 2009-06-23T19:33:58.400 に答える
0

「照合したいテキストが複数のタグにまたがる」というのは、次のような意味だと思います。

 In <i>this</i> example, I want to match "In this example".

 In <i><b>this</b></i> example, I also want to match "In this example".

 And <i>in <b>this</b></i> example, it's clear I have to ignore case too.

あなたが話している変換は整形式ではない XML になる可能性があるため、これは特に難しい問題のようです。たとえば、ここで部分文字列の周りにタグを配置しようとするとどうなるか見てください。

In this <i>example, putting tags around "in this example"</i> will break things.

<i>And in this</i> example, you have a similar problem.

整形式の出力を生成するには、おそらく次のようにする必要があります。

<bold>In this <i>example</i><bold><i>, putting tags around "in this example"</i> will break things.

<i>And <bold>in this</bold></i><bold> example</bold>, you have a similar problem.

理論的には、一致するすべての文字が異なる要素にある可能性があります。

Almost like <i><u>i</u><u>n</u> </i><u>th</u>is<i><i><u> ex</i>am</i>ple.</i>

ここには基本的に 2 つの問題があり、どちらも単純ではありません。

  1. XML のストリームで部分文字列を検索し、テキスト ノード以外はすべて無視して、ストリーム内の部分文字列の開始位置と終了位置を返します。

  2. XML ドキュメントへの 2 つの任意のインデックスを指定して、これらのインデックス間のテキストを囲む要素を作成し、タグが 2 つのインデックスの両方ではなくいずれか一方にまたがる要素を閉じます (そして再度開きます)。

ここでは、XSLT と正規表現が役に立たないことは明らかです。ここでも、DOM を使用しても役に立たないと思います。実際、パーサーの作成を伴わない 2 番目の問題に対する答えはないと思います。

これは本当の答えではありません、私は知っています。

于 2009-06-25T20:01:44.033 に答える