6

XHTML ドキュメントから抽出するテキストを正規化するには、XPath 関数 normalized-space() を使用する必要があります: http://test.anahnarciso.com/clean_bigbook_0.html

私は次の表現を使用しています。

//*[@slot="address"]/normalize-space(.)

これは、私が XPath 式をテストするために使用するツールである Qizx Studio で完全に機能します。

    let $doc := doc('http://test.anahnarciso.com/clean_bigbook_0.html')
    return $doc//*[@slot="address"]/normalize-space(.)

この単純なクエリは、一連の を返しますxs:string

144 Hempstead Tpke
403 West St
880 Old Country Rd
8412 164th St
8412 164th St
1 Irving Pl
1622 McDonald Ave
255 Conklin Ave
22011 Hempstead Ave
7909 Queens Blvd
11820 Queens Blvd
1027 Atlantic Ave
1068 Utica Ave
1002 Clintonville St
1002 Clintonville St
1156 Hempstead Tpke
Route 49
10007 Rockaway Blvd
12694 Willets Point Blvd
343 James St

ここで、Java コードで前の式を使用したいと考えています。

String exp = "//*[@slot=\"address"\"]/normalize-space(.)";
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile(exp);
Object result = expr.evaluate(doc, XPathConstants.NODESET);

しかし、最後の行は例外をスローします:

Cannot convert XPath value to Java object: required class is org.w3c.dom.NodeList; supplied value has type xs:string

明らかに、私はXPathConstants.NODESET何かを変えなければなりません。試しXPathConstants.STRINGましたが、シーケンスの最初の要素しか返されません。

文字列の配列のようなものを取得するにはどうすればよいですか?

前もって感謝します。

4

4 に答える 4

5

あなたの式は XPath 2.0 では機能しますが、XPath 1.0 (Java で使用されます) では違法です - である必要がありますnormalize-space(//*[@slot='address'])

とにかく、XPath 1.0 ではnormalize-space()、ノード セットで が呼び出されると、最初のノード (ドキュメント順) のみが取得されます。

やりたいことを実行するには、XPath 2.0 互換のパーサーを使用するか、結果のノード セットをトラバースしnormalize-space()てすべてのノードで呼び出す必要があります。

XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr;

String select = "//*[@slot='address']";
expr = xpath.compile(select);
NodeList result = (NodeList)expr.evaluate(input, XPathConstants.NODESET);

String normalize = "normalize-space(.)";
expr = xpath.compile(normalize);

int length = result.getLength();
for (int i = 0; i < length; i++) {
    System.out.println(expr.evaluate(result.item(i), XPathConstants.STRING));
}

...指定された出力を正確に出力します。

于 2012-07-07T21:01:20.097 に答える
3

使用している XPath のバージョンによって異なります。この投稿をチェックしてください。あなたの質問に答えてくれることを願っています: Is it possible to apply the normalize-space to all nodes XPath expression finds? 幸運を。

于 2012-07-07T20:51:25.680 に答える
3

ご指摘のとおり、XPath 2.0 式//*[@slot="address"]/normalize-space(.)は一連の文字列を返します。JAXP インターフェイスは XPath 2.0 をサポートするように設計されていないため、この戻り型は JAXPXPathConstantsクラスではサポートされていません。

これにより、次の 2 つの選択肢が残ります。

  1. XPath 2.0 用のネイティブ インターフェイスを備えているか、シーケンスを JAXP でサポートされている戻り値の型に変換できるXPath 2.0 プロセッサを使用します。
  2. XPath 1.0 式のみを使用してください。たとえば、あなたの場合、ターゲットノードを選択するだけです:

    //*[@slot="address"]
    

    次に、結果のノードセットを繰り返し、結果を配列または に収集しますList

式の評価に使用しているプロセッサと評価の開始に使用しているインターフェイスを区別することが重要であることに注意してください。

于 2012-07-07T21:00:47.560 に答える
3

:

//*[@slot="address"]/normalize-space(.)

は、構文的に正当な (そして実際に役立つ) XPath 2.0 式です。

XPath 1.0 では、同じ式は構文的に正しくありません。ロケーション ステップを関数呼び出しにすることはできません。

実際、 XPath 1.0 式を1 つ記述することはできません。その評価結果は、必要な文字列のセットです。

XPath 2.0 を実装する製品 (Saxon 9.x など) をプログラムで使用する必要があります。

于 2012-07-07T21:01:07.197 に答える