0

次のような PCDATA 要素を含む XML ファイルを処理する必要があります。

<corpus id="c01">
  <text id="t01>
    <sentence id="s01">Mary <instance id="i01">had</instance> a <instance id="i02">lamb</instance>.</sentence>
    <sentence id="s02">...</sentence>
    ...
  </text>
  ...
</corpus>

各 <text> の <sentence> ごとに、文 ID とその文に含まれる全文を含むデータ構造を設定する必要があります。次に、各 <instance> に対して、インスタンス ID と文内の開始位置と終了位置を含むデータ構造を設定する必要があります。(空白が正規化されているかどうかは気にしません。)

したがって、上記の例では、基本的に次のものが必要です。

s.id = "s01"
s.text = "Mary had a lamb."
i1.id = "i01"
i1.start = 6
i1.end = 8
i2.id = "i02"
i2.start = 12
i2.end = 15

dom4jでこれを行う方法はありますか? Element.getText() メソッドは子要素のテキストをスキップします。別の要素内の要素のオフセットを与えるメソッドは見当たりません。dom4j がこのタスクに適していない場合、より優れたツールは何ですか?

4

1 に答える 1

0

確かに実行可能ですが、少し作業が必要です。ツリー内のどこにあるかを追跡し、進行中にテキストとインスタンスのオフセットを蓄積する Visitor を作成できます。ただし、そのソリューションは、SAX ハンドラーによって直接実装することもできます。これは、はるかに高速です。

これにより、最初に何かが得られるはずです。

public class Main extends DefaultHandler {

StringBuilder buf = new StringBuilder();
boolean collecting = false;
int ic = 0;

@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    if (localName.equals("sentence")) {
        System.out.printf("s.id=%s\n", attributes.getValue("id"));
        collecting = true;
        buf.setLength(0);
        ic = 0;
    } else if (localName.equals("instance")) {
        ++ic;
        System.out.printf("i%d.id=%s\n", ic, attributes.getValue("id"));
        System.out.printf("i%d.start=%s\n", ic, buf.length());
    }

}

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    if (localName.equals("sentence")) {
        collecting = false;
        System.out.printf("s.text=%s\n", buf.toString());
    } else if (localName.equals("instance")) {
        System.out.printf("i%d.end=%s\n", ic, buf.length());
    }
}

@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {
    if (collecting) {
        buf.append(ch, start, length);
    }
}

public static void main(String[] args) throws Exception {

    SAXParserFactory f = SAXParserFactory.newInstance();
    f.setNamespaceAware(true);
    f.newSAXParser().parse(Main.class.getResourceAsStream("data.xml"),
            new Main());
}
}
于 2011-10-25T14:49:35.397 に答える