Alexis Dufrenoy
Alexis Dufrenoy

Reputation: 11946

Jsoup is not escaping entities in string like it should

I created a method to strip some elements from HTML using Jsoup, but Jsoup is not escaping the accented characters like it should.

Here is my code, with a main() to test, so it's self-contained and executable:

public class JsoupWrapper {

    public static void main(String[] args) {
        String s = "<p style=\"text-align: justify;\">Cet amendement vise &#224; rectifier le montant des annulations sur le programme 181 &#171;&#160;Pr&#233;vention des risques&#160;&#187;, de la mission &#171;&#160;&#201;cologie, d&#233;veloppement et mobilit&#233;s durables&#160;&#187;, en l&#8217;abaissant de 24,2&#160;M&#8364;.</p>\n" +
                "<p style=\"text-align: justify;\">Cette minoration des annulations est propos&#233;e dans le cadre du red&#233;ploiement de cr&#233;dits du programme d&#8217;investissements d&#8217;avenir (PIA) depuis les actions du PIA port&#233;es par l&#8217;Agence de l&#8217;environnement et de la ma&#238;trise de l&#8217;&#233;nergie (ADEME), vers l&#8217;action &#171;&#160;Equipex&#160;&#187; port&#233;e par l&#8217;Agence nationale de la recherche (ANR), pour financer les projets &#171;&#160;Microcarb&#160;&#187; et &#171;&#160;Polar Pod&#160;&#187;. Le red&#233;ploiement concernera pour l&#8217;ADEME l&#8217;action &#171;&#160;V&#233;hicules et transporteurs du futur&#160;&#187;, &#224; hauteur de 40&#160;M&#8364; et l&#8217;action &#171;&#160;D&#233;monstrateurs de la transition &#233;nerg&#233;tique&#160;&#187;, &#224; hauteur de 10,8&#160;M&#8364;. Le soutien aux deux projets &#171;&#160;Microcarb&#160;&#187; et &#171;&#160;Polar Pod&#160;&#187; demeure complet, cette modification constituant un simple ajustement qui permet, tout en maintenant le soutien &#224; &#171;&#160;Polar Pod&#160;&#187; et &#171;&#160;Microcarb&#160;&#187;, de pr&#233;server des moyens sur l&#8217;action &#171;&#160;V&#233;hicules et transporteurs du futur&#160;&#187; du PIA en vue de la conclusion des assises de la mobilit&#233;.</p>\n" +
                "<p style=\"text-align: justify;\">Cet amendement est compl&#233;t&#233; par un amendement miroir sur le programme 172 &#171;&#160;Recherches scientifiques et technologiques pluridisciplinaires&#160;&#187;, de la mission &#171;&#160;Recherche et enseignement sup&#233;rieur&#160;&#187;.</p>";
        System.out.println(cleanToBeforeRevision(s));
    }

    public static String cleanToBeforeRevision(String html) {
        if (html == null) {
            return null;
        }
        org.jsoup.nodes.Document doc = Jsoup.parse(html);

        // This should normally do the trick
        doc.outputSettings().prettyPrint(false).escapeMode(Entities.EscapeMode.extended);

        Elements toReverts = doc.select("span.ins");
        Elements toRestores = doc.select("span.del, span[data-userid], span[data-username]");

        toReverts.forEach(Node::remove);

        toRestores.forEach(toRestore->{
            TextNode text = new TextNode(toRestore.html());
            toRestore.replaceWith(text);
        });

        return doc.body().html();
    }
}

The à, for example, should be replaced by a &agrave;, the é by a &eacute;, etc. However, that's not the case.

I'm using Jsoup 1.12.1.

Edit: I want everything except the HTML special characters (<, >, "...) to be encoded. Especially acccented characters. The result still needs to be HTML.

Upvotes: 0

Views: 428

Answers (1)

Alias Cartellano
Alias Cartellano

Reputation: 364

You can pass your doc string to the escapeHtml4() or escapeHtml3() method of StringEscapeUtils from org.apache.commons.text to solve your problem:

Code:

import org.jsoup.*;
import org.jsoup.nodes.Entities;
import org.apache.commons.text.*;

public class MyClass {
    public static void main(String[] args) {
        String strHTMLInput = "<p style=\"text-align: justify;\">Cet amendement vise &#224; rectifier le montant des annulations sur le programme 181 &#171;&#160;Pr&#233;vention des risques&#160;&#187;, de la mission &#171;&#160;&#201;cologie, d&#233;veloppement et mobilit&#233;s durables&#160;&#187;, en l&#8217;abaissant de 24,2&#160;M&#8364;.</p>\n" +
                "<p style=\"text-align: justify;\">Cette minoration des annulations est propos&#233;e dans le cadre du red&#233;ploiement de cr&#233;dits du programme d&#8217;investissements d&#8217;avenir (PIA) depuis les actions du PIA port&#233;es par l&#8217;Agence de l&#8217;environnement et de la ma&#238;trise de l&#8217;&#233;nergie (ADEME), vers l&#8217;action &#171;&#160;Equipex&#160;&#187; port&#233;e par l&#8217;Agence nationale de la recherche (ANR), pour financer les projets &#171;&#160;Microcarb&#160;&#187; et &#171;&#160;Polar Pod&#160;&#187;. Le red&#233;ploiement concernera pour l&#8217;ADEME l&#8217;action &#171;&#160;V&#233;hicules et transporteurs du futur&#160;&#187;, &#224; hauteur de 40&#160;M&#8364; et l&#8217;action &#171;&#160;D&#233;monstrateurs de la transition &#233;nerg&#233;tique&#160;&#187;, &#224; hauteur de 10,8&#160;M&#8364;. Le soutien aux deux projets &#171;&#160;Microcarb&#160;&#187; et &#171;&#160;Polar Pod&#160;&#187; demeure complet, cette modification constituant un simple ajustement qui permet, tout en maintenant le soutien &#224; &#171;&#160;Polar Pod&#160;&#187; et &#171;&#160;Microcarb&#160;&#187;, de pr&#233;server des moyens sur l&#8217;action &#171;&#160;V&#233;hicules et transporteurs du futur&#160;&#187; du PIA en vue de la conclusion des assises de la mobilit&#233;.</p>\n" +
                "<p style=\"text-align: justify;\">Cet amendement est compl&#233;t&#233; par un amendement miroir sur le programme 172 &#171;&#160;Recherches scientifiques et technologiques pluridisciplinaires&#160;&#187;, de la mission &#171;&#160;Recherche et enseignement sup&#233;rieur&#160;&#187;.</p>";
        org.jsoup.nodes.Document doc = Jsoup.parse(strHTMLInput);

        // This should normally do the trick
        doc.outputSettings().prettyPrint(false).escapeMode(Entities.EscapeMode.extended);
        String strEscapeHTML = StringEscapeUtils.escapeHtml3(doc.body().html());
        System.out.println("Escaped HTML >>> " + strEscapeHTML);
    }
}

Output:

Escaped HTML >>> &lt;p style=&quot;text-align: justify;&quot;&gt;Cet amendement vise &agrave; rectifier le montant des annulations sur le programme 181 &laquo;&amp;nbsp;Pr&eacute;vention des risques&amp;nbsp;&raquo;, de la mission &laquo;&amp;nbsp;&Eacute;cologie, d&eacute;veloppement et mobilit&eacute;s durables&amp;nbsp;&raquo;, en l’abaissant de 24,2&amp;nbsp;M€.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;Cette minoration des annulations est propos&eacute;e dans le cadre du red&eacute;ploiement de cr&eacute;dits du programme d’investissements d’avenir (PIA) depuis les actions du PIA port&eacute;es par l’Agence de l’environnement et de la ma&icirc;trise de l’&eacute;nergie (ADEME), vers l’action &laquo;&amp;nbsp;Equipex&amp;nbsp;&raquo; port&eacute;e par l’Agence nationale de la recherche (ANR), pour financer les projets &laquo;&amp;nbsp;Microcarb&amp;nbsp;&raquo; et &laquo;&amp;nbsp;Polar Pod&amp;nbsp;&raquo;. Le red&eacute;ploiement concernera pour l’ADEME l’action &laquo;&amp;nbsp;V&eacute;hicules et transporteurs du futur&amp;nbsp;&raquo;, &agrave; hauteur de 40&amp;nbsp;M€ et l’action &laquo;&amp;nbsp;D&eacute;monstrateurs de la transition &eacute;nerg&eacute;tique&amp;nbsp;&raquo;, &agrave; hauteur de 10,8&amp;nbsp;M€. Le soutien aux deux projets &laquo;&amp;nbsp;Microcarb&amp;nbsp;&raquo; et &laquo;&amp;nbsp;Polar Pod&amp;nbsp;&raquo; demeure complet, cette modification constituant un simple ajustement qui permet, tout en maintenant le soutien &agrave; &laquo;&amp;nbsp;Polar Pod&amp;nbsp;&raquo; et &laquo;&amp;nbsp;Microcarb&amp;nbsp;&raquo;, de pr&eacute;server des moyens sur l’action &laquo;&amp;nbsp;V&eacute;hicules et transporteurs du futur&amp;nbsp;&raquo; du PIA en vue de la conclusion des assises de la mobilit&eacute;.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot;&gt;Cet amendement est compl&eacute;t&eacute; par un amendement miroir sur le programme 172 &laquo;&amp;nbsp;Recherches scientifiques et technologiques pluridisciplinaires&amp;nbsp;&raquo;, de la mission &laquo;&amp;nbsp;Recherche et enseignement sup&eacute;rieur&amp;nbsp;&raquo;.&lt;/p&gt;

Note: You may want to reapply the missing segments from your code.

Edit:

Since it was requested that html special characters remain unchanged, I devised the following:

Code:

import org.jsoup.*;
import org.jsoup.nodes.Entities;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.apache.commons.text.*;

public class MyClass {
    public static void main(String[] args) {
        String strHTMLInput = "<p style=\"text-align: justify;\">Cet amendement vise &#224; rectifier le montant des annulations sur le programme 181 &#171;&#160;Pr&#233;vention des risques&#160;&#187;, de la mission &#171;&#160;&#201;cologie, d&#233;veloppement et mobilit&#233;s durables&#160;&#187;, en l&#8217;abaissant de 24,2&#160;M&#8364;.</p>\n" +
                "<p style=\"text-align: justify;\">Cette minoration des annulations est propos&#233;e dans le cadre du red&#233;ploiement de cr&#233;dits du programme d&#8217;investissements d&#8217;avenir (PIA) depuis les actions du PIA port&#233;es par l&#8217;Agence de l&#8217;environnement et de la ma&#238;trise de l&#8217;&#233;nergie (ADEME), vers l&#8217;action &#171;&#160;Equipex&#160;&#187; port&#233;e par l&#8217;Agence nationale de la recherche (ANR), pour financer les projets &#171;&#160;Microcarb&#160;&#187; et &#171;&#160;Polar Pod&#160;&#187;. Le red&#233;ploiement concernera pour l&#8217;ADEME l&#8217;action &#171;&#160;V&#233;hicules et transporteurs du futur&#160;&#187;, &#224; hauteur de 40&#160;M&#8364; et l&#8217;action &#171;&#160;D&#233;monstrateurs de la transition &#233;nerg&#233;tique&#160;&#187;, &#224; hauteur de 10,8&#160;M&#8364;. Le soutien aux deux projets &#171;&#160;Microcarb&#160;&#187; et &#171;&#160;Polar Pod&#160;&#187; demeure complet, cette modification constituant un simple ajustement qui permet, tout en maintenant le soutien &#224; &#171;&#160;Polar Pod&#160;&#187; et &#171;&#160;Microcarb&#160;&#187;, de pr&#233;server des moyens sur l&#8217;action &#171;&#160;V&#233;hicules et transporteurs du futur&#160;&#187; du PIA en vue de la conclusion des assises de la mobilit&#233;.</p>\n" +
                "<p style=\"text-align: justify;\">Cet amendement est compl&#233;t&#233; par un amendement miroir sur le programme 172 &#171;&#160;Recherches scientifiques et technologiques pluridisciplinaires&#160;&#187;, de la mission &#171;&#160;Recherche et enseignement sup&#233;rieur&#160;&#187;.</p>";
        org.jsoup.nodes.Document doc = Jsoup.parse(strHTMLInput);
        
        // This should normally do the trick
        doc.outputSettings().prettyPrint(false).escapeMode(null);
        String strUnescapeHTML = StringEscapeUtils.unescapeHtml4(doc.body().html());
        String strEscapeHTML = StringEscapeUtils.escapeHtml4(strUnescapeHTML);
        String unescapeHtml=strEscapeHTML;
        Elements elements=doc.body().children();
        for(Element element: elements){
            element.text(StringEscapeUtils.escapeHtml4(element.text()));
        }

        
        System.out.println("\nUnescaped HTML >>> " + strUnescapeHTML);
        System.out.println("\nEscaped HTML >>> " + StringEscapeUtils.unescapeXml(doc.body().html()));
    }
}

Output:

Unescaped HTML >>> <p style="text-align: justify;">Cet amendement vise à rectifier le montant des annulations sur le programme 181 « Prévention des risques », de la mission « Écologie, développement et mobilités durables », en l’abaissant de 24,2 M€.</p>
<p style="text-align: justify;">Cette minoration des annulations est proposée dans le cadre du redéploiement de crédits du programme d’investissements d’avenir (PIA) depuis les actions du PIA portées par l’Agence de l’environnement et de la maîtrise de l’énergie (ADEME), vers l’action « Equipex » portée par l’Agence nationale de la recherche (ANR), pour financer les projets « Microcarb » et « Polar Pod ». Le redéploiement concernera pour l’ADEME l’action « Véhicules et transporteurs du futur », à hauteur de 40 M€ et l’action « Démonstrateurs de la transition énergétique », à hauteur de 10,8 M€. Le soutien aux deux projets « Microcarb » et « Polar Pod » demeure complet, cette modification constituant un simple ajustement qui permet, tout en maintenant le soutien à « Polar Pod » et « Microcarb », de préserver des moyens sur l’action « Véhicules et transporteurs du futur » du PIA en vue de la conclusion des assises de la mobilité.</p>
<p style="text-align: justify;">Cet amendement est complété par un amendement miroir sur le programme 172 « Recherches scientifiques et technologiques pluridisciplinaires », de la mission « Recherche et enseignement supérieur ».</p>

Escaped HTML >>> <p style="text-align: justify;">Cet amendement vise &agrave; rectifier le montant des annulations sur le programme 181 &laquo; Pr&eacute;vention des risques &raquo;, de la mission &laquo; &Eacute;cologie, d&eacute;veloppement et mobilit&eacute;s durables &raquo;, en l&rsquo;abaissant de 24,2 M&euro;.</p>
<p style="text-align: justify;">Cette minoration des annulations est propos&eacute;e dans le cadre du red&eacute;ploiement de cr&eacute;dits du programme d&rsquo;investissements d&rsquo;avenir (PIA) depuis les actions du PIA port&eacute;es par l&rsquo;Agence de l&rsquo;environnement et de la ma&icirc;trise de l&rsquo;&eacute;nergie (ADEME), vers l&rsquo;action &laquo; Equipex &raquo; port&eacute;e par l&rsquo;Agence nationale de la recherche (ANR), pour financer les projets &laquo; Microcarb &raquo; et &laquo; Polar Pod &raquo;. Le red&eacute;ploiement concernera pour l&rsquo;ADEME l&rsquo;action &laquo; V&eacute;hicules et transporteurs du futur &raquo;, &agrave; hauteur de 40 M&euro; et l&rsquo;action &laquo; D&eacute;monstrateurs de la transition &eacute;nerg&eacute;tique &raquo;, &agrave; hauteur de 10,8 M&euro;. Le soutien aux deux projets &laquo; Microcarb &raquo; et &laquo; Polar Pod &raquo; demeure complet, cette modification constituant un simple ajustement qui permet, tout en maintenant le soutien &agrave; &laquo; Polar Pod &raquo; et &laquo; Microcarb &raquo;, de pr&eacute;server des moyens sur l&rsquo;action &laquo; V&eacute;hicules et transporteurs du futur &raquo; du PIA en vue de la conclusion des assises de la mobilit&eacute;.</p>
<p style="text-align: justify;">Cet amendement est compl&eacute;t&eacute; par un amendement miroir sur le programme 172 &laquo; Recherches scientifiques et technologiques pluridisciplinaires &raquo;, de la mission &laquo; Recherche et enseignement sup&eacute;rieur &raquo;.</p>

You can just escape all the text inside the elements(using element.text()) to preserve the tags, however, you will have to use StringEscapeUtils.unescapeXml() in order to remove extra &amps; added by the 'Document' when you plan on using the string.

References: SO: jsoup encode special characters.

Upvotes: 1

Related Questions