114 votes

Comment faire pour préserver les sauts de ligne lors de l'utilisation de jsoup pour convertir html en texte brut?

J'ai le code suivant:

   public class NewClass {
        public String noTags(String str){
            return Jsoup.parse(str).text();
        }


      public static void main(String args[]) {
       String strings="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN \">" +
        "<HTML> <HEAD> <TITLE></TITLE> <style>body{ font-size: 12px;font-family: verdana, arial, helvetica, sans-serif;}</style> </HEAD> <BODY><p><b>hello world</b></p><p><br><b>yo</b> <a href=\"http://google.com\">googlez</a></p></BODY> </HTML> ";
  NewClass text = new NewClass();
      System.out.println((text.noTags(strings)));


}

Et j'ai le résultat:

hello world yo googlez

Mais j'ai envie de casser la ligne:

hello world
yo googlez

J'ai regardé jsoup de TextNode#getWholeText() mais je n'arrive pas à comprendre comment l'utiliser.

Si il y a un <br> dans le balisage, je l'analyse, comment puis-je obtenir un saut de ligne dans mon résultant de la sortie?

112voto

user121196 Points 5372

La vraie solution qui préserve mais les sauts de ligne devrait ressembler à ceci:

public static String br2nl(String html) {
    if(html==null)
        return html;
    Document document = Jsoup.parse(html);
    document.outputSettings(new Document.OutputSettings().prettyPrint(false));//makes html() preserve linebreaks and spacing
    document.select("br").append("\\n");
    document.select("p").prepend("\\n\\n");
    String s = document.html().replaceAll("\\\\n", "\n");
    return Jsoup.clean(s, "", Whitelist.none(), new Document.OutputSettings().prettyPrint(false));
}

Il satisfait aux exigences suivantes:

1. si l'original du code html contient un saut de ligne(\n), elle est préservée
2. si le html d'origine contient br / ou les balises p, ils se traduit de saut de ligne(\n).

46voto

Mirco Attocchi Points 343

Avec

Jsoup.parse("A\nB").text();

vous avez de sortie

"A B" 

et pas

A

B

Pour cela, je suis en utilisant:

text = Jsoup.parse(html.replaceAll("(?i)<br[^>]*>", "br2n")).text();
text = descrizione.replaceAll("br2n", "\n");

45voto

Paulius Z Points 119
Jsoup.clean(unsafeString, "", Whitelist.none(), new OutputSettings().prettyPrint(false));

Nous sommes à l'aide de cette méthode ici:

public static String clean(String bodyHtml,
                       String baseUri,
                       Whitelist whitelist,
                       Document.OutputSettings outputSettings)

En passant c' Whitelist.none() nous nous assurons que tout le code HTML est supprimé.

Par la disparition new OutputSettings().prettyPrint(false) nous assurez-vous que la sortie n'est pas reformaté et les sauts de ligne sont conservés.

24voto

mkowa Points 41

Essayez ceci en utilisant jsoup:

public static String cleanPreserveLineBreaks(String bodyHtml) {

    // get pretty printed html with preserved br and p tags
    String prettyPrintedBodyFragment = Jsoup.clean(bodyHtml, "", Whitelist.none().addTags("br", "p"), new OutputSettings().prettyPrint(true));
    // get plain text with preserved line breaks by disabled prettyPrint
    return Jsoup.clean(prettyPrintedBodyFragment, "", Whitelist.none(), new OutputSettings().prettyPrint(false));
}

7voto

popcorny Points 231

Vous pouvez traverser un élément donné

public String convertNodeToText(Element element)
{
    final StringBuilder buffer = new StringBuilder();

    new NodeTraversor(new NodeVisitor() {
        boolean isNewline = true;

        @Override
        public void head(Node node, int depth) {
            if (node instanceof TextNode) {
                TextNode textNode = (TextNode) node;
                String text = textNode.text().replace('\u00A0', ' ').trim();                    
                if(!text.isEmpty())
                {                        
                    buffer.append(text);
                    isNewline = false;
                }
            } else if (node instanceof Element) {
                Element element = (Element) node;
                if (!isNewline)
                {
                    if((element.isBlock() || element.tagName().equals("br")))
                    {
                        buffer.append("\n");
                        isNewline = true;
                    }
                }
            }                
        }

        @Override
        public void tail(Node node, int depth) {                
        }                        
    }).traverse(element);        

    return buffer.toString();               
}

Et pour votre code

String result = convertNodeToText(JSoup.parse(html))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X