防止Jsoup丢弃额外的空格

时间:2011-03-28 02:52:36

标签: java jsoup

我正在使用Jsoup来清理表单中的用户输入。有问题的表单包含一个需要纯文本的<textarea>。提交表单后,我用Jsoup.clean(textareaContents)清除输入;但是,由于html忽略了额外的空格,Jsoup.clean()将从输入中删除有价值的空白字符。

例如,如果有人在textarea中输入了一些文字行:

hello

test
Jsoup.clean()之后

,您将拥有:

hello test

如何让Jsoup.clean()保留空白?我知道它是为解析html而设计的,这不是html,所以有更好的选择吗?

3 个答案:

答案 0 :(得分:9)

对于后代,如果您仍需要使用空格访问原始文本,则可以使用TextNode.getWholeText()方法。

示例代码:

/**
 * @param cell element that contains whitespace formatting
 * @return
 */
public static String getText(Element cell) {
    String text = null;
    List<Node> childNodes = cell.childNodes();
    if (childNodes.size() > 0) {
        Node childNode = childNodes.get(0);
        if (childNode instanceof TextNode) {
            text = ((TextNode)childNode).getWholeText();
        }
    }
    if (text == null) {
        text = cell.text();
    }
    return text;
}

在上面的代码中,我们假设传入的元素直接在元素体内包含文本内容(我们采用第一个节点)。如果不是这样,它将回归常规Element.text()方法。

答案 1 :(得分:4)

如果你的textarea只是想要纯文本,那么我认为你最好只用HTML转义纯文本。即将用户的输入<>标记分别转换为&lt;&gt;。输入我们的输出(输入可能更安全,所以你只需要考虑一次)。

正如你所说,jsoup HTML cleaner旨在解析不受信任的输入HTML和outuput trusted HTML,其中格式化是通过元素完成的。

答案 2 :(得分:2)

Neeme Praks&#39;答案是非常好的,保存正确的空白。但是,内联HTML真的搞砸了。

<span>This is<br />some text.  Cool story.</span>

结果

"This is"

或者,如果传入的元素没有自己的文本,则返回null。

所以我不得不为我的目的重新修改这个方法。这可能会帮助一些人,所以我在这里发布它。基本的想法是迭代孩子而不是仅仅采取第一个。这还包括为没有子项的任何元素抓取HTML的情况。

这样原始片段会返回:

This is<br />some text.  Cool story.
public static String getText(Element cell) {
    StringBuilder textBuilder = new StringBuilder();
    for (Node node : cell.childNodes()) {
        if (node instanceof TextNode) {
            textBuilder.append(((TextNode)node).getWholeText());
        }
        else {
            for (Node childNode : node.childNodes()) {
                textBuilder.append(getText((Element)childNode));
            }
            textBuilder.append(node.outerHtml());
        }
    }
    if (cell.childNodes().isEmpty()) {
        textBuilder.append(cell.outerHtml());
    }
    return textBuilder.toString();
}