2017-05-10 3 views
0

Ich verwende derzeit die Java XPath-API, um Text aus einem String zu extrahieren.Java XPath API stripping HTML-Tags aus Text

Dieser String hat jedoch oft HTML-Formatierung (<b>, <em>, <sub>, usw.). Wenn ich meinen Code ausführe, werden die HTML-Tags entfernt. Gibt es eine Möglichkeit, dies zu vermeiden?

ist hier ein Abtastwerteingang:

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

Hier ein Ausschnitt aus meinem Code ist:

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

Hier ist die aktuelle Ausgabe:

The dog jumped over the fence. 

Hier wird der Ausgang I wollen:

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

Vielen Dank im Voraus für Ihre Hilfe.

+0

Haben Sie die Möglichkeit, die Werte, die die Methode xPath.evaluate (string, var) tut das? Betrachten Sie beispielsweise den xPath-Punktoperator und sehen Sie, ob Sie fett gedruckte Texte vermeiden können. – ElementCR

Antwort

1

Eine einfache geradeaus (aber vielleicht nicht sehr effizient) Lösung:

/** 
* 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(); 
} 

Dann wird die XPath Auswertung der Knoten anstelle der Zeichenfolge zurückgeben sollte:

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

Funktioniert gut, danke! – user1472409

0

Als Teil des Parsers liest es den Text als XML und klassifiziert den Inhalt der Knotenzusammenfassung als Text, Knoten, Text. Wenn Sie/document/summary verwenden, gibt der Resolver eine Zeichenfolge zurück, die aus allen Nachkommen des ausgewählten Knotens besteht. Dies gibt Ihnen text + node.text + text. Aus diesem Grund verlieren Sie das fett gedruckte Tag. Die Eingabezeichenfolge innerhalb der Zusammenfassung sollte entweder:

  • HTML codiert -oder
  • in einem CDATA-Tag enthalten.

Wrapping innerhalb von CDATA-Tag behandelt die den Inhalt als Text:

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

Das Problem mit Ihrer Lösung ist, dass der Parser so gut XML-Struktur behandeln will. Wenn Sie in der Zusammenfassung ein unausgewogenes Tag hatten, würden Sie eine Ausnahme erhalten.

Die Lösung für Ihre Frage wäre, die Elemente zu durchlaufen, um Textdaten zu erhalten, während die Knotennamen erhalten bleiben. Dies kann für Ihr Beispiel funktioniert, aber wenn Sie einen unausgewogenen Tag haben wird es brechen:

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

Verwenden Sie diese Lösung keine Daten zwischen der Zusammenfassung Tag zu analysieren. Verwenden Sie stattdessen entweder CDATA oder verwenden Sie eine Art Regex, um Inhalt zwischen Start- und Endpunkten zu erhalten.

+0

Danke für Ihre Hilfe. Die Eingabe kommt von einer statischen Datenbank, so dass ich nicht sicher bin, ob ich die Daten bearbeiten kann. – user1472409

+0

Die Lösung ist korrekt, aber '' ... '' sind nicht "ungültig". Sie stellen einfach einen XML-Elementteil der Dokumentstruktur statt Text dar. Wenn Sie alles in eine CDATA einfügen, wird der gesamte Inhalt wie Text behandelt. – VGR

+0

@VGR - Sie haben Recht - nicht für den Parser ungültig, nur verschiedene Elementtypen. Aktualisiert, um weitere Informationen anzuzeigen. – eDog

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

Erhalten Kinder aus diese Zeichenfolge. Sie werden 2 Textknoten und einen Elementknoten haben. Behandle sie entsprechend.