2017-05-10 10 views
0

現在、Java XPath APIを使用して文字列からテキストを抽出しています。Java XPath APIテキストからHTMLタグを取り除く

しかし、この文字列は多くの場合、HTML形式(<b>,<em><sub>など)です。コードを実行すると、HTMLタグが削除されます。これを避ける方法はありますか?ここで

は、サンプル入力である:ここで

<document> 
    <summary> 
    The <b>dog</b> jumped over the fence. 
    </summary> 
</document> 

は、私のコードの抜粋である:ここで

XPathFactory factory = XPathFactory.newInstance(); 
XPath xPath = factory.newXPath(); 
InputSource source = new InputSource(new StringReader(xml)); 
String output = xPath.evaluate("/document/summary", source); 

は、現在出力されます。ここでは

The dog jumped over the fence. 

は出力Iです欲しいもの:

The <b>dog</b> jumped over the fence. 

ご協力いただきありがとうございます。

+0

メソッドxPathの値を増やすことはできますか。評価する(文字列、var)ですか?たとえば、xPathのドット演算子を見て、太字のテキストを避けることができるかどうかを確認します。 – ElementCR

答えて

1

簡単なまっすぐ進む(しかし、そうでないかもしれない、非常に効率的な)解決策:

/** 
* Serializes a XML node to a string representation without XML declaration 
* 
* @param node The XML node 
* @return The string representation 
* @throws TransformerFactoryConfigurationError 
* @throws TransformerException 
*/ 
private static String node2String(Node node) throws TransformerFactoryConfigurationError, TransformerException { 
    final Transformer transformer = TransformerFactory.newInstance().newTransformer(); 
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
    final StringWriter writer = new StringWriter(); 
    transformer.transform(new DOMSource(node), new StreamResult(writer)); 
    return writer.toString(); 
} 

/** 
* Serializes the inner (child) nodes of a XML element. 
* @param el 
* @return 
* @throws TransformerFactoryConfigurationError 
* @throws TransformerException 
*/ 
private static String elementInner2String(Element el) throws TransformerFactoryConfigurationError, TransformerException { 
    final NodeList children = el.getChildNodes(); 
    final StringBuilder sb = new StringBuilder(); 
    for(int i = 0; i < children.getLength(); i++) { 
    final Node child = children.item(i); 
    sb.append(node2String(child)); 
    } 
    return sb.toString(); 
} 

そして、XPath評価は、文字列の代わりにノードを返す必要があります:

Element summaryElement = (Element) xpath.evaluate("/document/summary", doc, XPathConstants.NODE); 
String output = elementInner2String(summaryElement); 
+0

うまく動作します、ありがとう! – user1472409

0

パーサの一部として、テキストをXMLとして読み込み、ノードサマリーの内容をtext、node、textとして分類します。/document/summaryを使用すると、リゾルバは選択されたノードのすべての子孫で構成される文字列を返します。これにより、text + node.text + textが得られます。これが太字タグを失う理由です。要約の内部入力文字列がある必要があり、次のいずれか

  • HTMLは、CDATAタグに包ま
  • - または - エンコードされました。 CDATAタグの内部

ラッピングは、テキストなどのコンテンツを扱います:

<document> 
<summary> 
    <![CDATA[The <b>dog</b> jumped over the fence.]]> 
</summary> 

あなたの解決策の問題は、パーサが良いXML構造として扱いたいということです。要約内にアンバランスなタグがある場合、例外が発生します。

あなたの質問に対する解決策は、ノード名を保持しながらテキストデータを取得するために要素をループすることです。これはあなたの例のために働くことがあり、しかし、あなたはそれが破壊されるアンバランスなタグがある場合:

The <b>dog</b> jumped over <br> the fence 

を要約タグとの間でデータを解析するために、このソリューションを使用しないでください。代わりに、CDATAを使うか、ある種の正規表現を使って開始点と終了点の間に内容を取得してください。

+0

ご協力ありがとうございます。入力は静的なデータベースから来ているので、データを編集できるかどうかはわかりません。 – user1472409

+0

解決策は正しいですが、 '' ... ' 'は「無効」ではありません。単純に、テキストではなく文書構造のXML要素を表します。すべてをCDATAに入れると、内容全体がテキストのように扱われます。 – VGR

+0

@VGR - あなたは正しいです - パーサーにとっては無効ではなく、異なる要素タイプだけです。詳細情報が表示されるように更新されました。 – eDog

0
The <b>dog</b> jumped over the fence 

から子どもたちを取得しますこの文字列。 2つのテキストノードと1つの要素ノードがあります。それに応じてそれらを扱う。

関連する問題