使用jsoup解析保留非HTML元素

时间:2016-04-20 19:57:08

标签: java html jsoup webcenter

我是jsoup的新手,我在使用非HTML元素(脚本)时遇到了一些困难。我有以下HTML:

<$if not dcSnippet$>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="generator" content="Outside In HTML Converter version 8.4.0"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title></title>
</head>

<$endif$>
<div style="position:relative">
<p style="text-align: left; font-family: times; font-size: 10pt; font-weight: normal; font-style: normal; text-decoration: none"><span style="font-weight: normal; font-style: normal">This is a test document.</span></p>
</div>
<$if not dcSnippet$>
</body>
</html>
<$endif$>

用于显示此应用程序的应用程序知道如何处理这些&lt; if dcSnippet $&gt;等声明。所以,当我简单地用jsoup解析文本时,&lt;和&gt;编码并重新组织html,因此它不会正确执行或显示。像这样:

<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>&lt;$if not dcSnippet$&gt;
<meta http-equiv="generator" content="Outside In HTML Converter version 8.4.0">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
&lt;$endif$&gt;
<div style="position:relative">
<p style="text-align: left; font-family: times; font-size: 10pt; font-weight: normal; font-style: normal; text-decoration: none"><span style="font-weight: normal; font-style: normal">This is a test document.</span></p>
</div>
&lt;$if not dcSnippet$&gt;
&lt;$endif$&gt;
</body></html> 

我的最终目标是我想添加一些css和js包含,并修改一些元素属性。这不是一个真正的问题,我已经解决了这个问题。问题是我不知道如何保留非HTML元素并将格式保留在与原始格式相同的位置。到目前为止我的解决方案是这样的:

  1. 读入HTML文件,并遍历它,删除带有非html元素的行。
  2. 使用纯HTML
  3. 创建一个Document对象
  4. 进行修改
  5. 返回HTML并重新插入我先删除的非HTML元素(脚本)。
  6. 将文档保存到文件系统
  7. 现在,只要非HTML的位置是可预测的,并且到目前为止,这是有效的。但我想知道是否有更好的方法来做到这一点,所以我不必先“清理”HTML,然后手动重新引入我后来删除的内容。这是我的代码的要点(希望我没有错过太多的声明):

    String newLine();
    FileReader fr = new FileReader(inputFile);
    BufferedReader br = new BufferedReader(fr);
    while ((thisLine = br.readLine()) != null) {
        if (thisLine.matches(".*<\\$if.*\\$>")) {
            ifStatement = thisLine + "\n";
        } else if (thisLine.matches(".*<\\$endif\\$>")) {
            endifStatement = thisLine + "\n";
        } else { 
            tempHtml += thisLine + "\n";
        }
    }
    br.close();
    
    Document doc = Jsoup.parse(tempHtml, "UTF-8");
    doc.outputSettings().prettyPrint(false).escapeMode(EscapeMode.extended);
    
    Element head = doc.head();
    Element body = doc.body();
    Element firstDiv = body.select("div").first();
    
    [... perform my element and attribute inserts ...]
    
    body.prependText("\n" + endifStatement);
    body.appendText("\n" + ifStatement);
    String fullHtml = (ifStatement + doc.toString().replaceAll("\\&lt;", "<").replaceAll("\\&gt;", ">") + "\n" + endifStatement);
    
    BufferedWriter htmlWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8"));
    htmlWriter.write(fullHtml);
    htmlWriter.flush();
    htmlWriter.close();
    

    非常感谢任何帮助或输入!

1 个答案:

答案 0 :(得分:0)

  

问题是我不知道如何保留非HTML元素并将格式保留在与原始元素相同的位置。

Jsoup是一个HTML解析器。您提供的&#34; HTML文件&#34; 不包含HTML。它是一个用类似HTML语言编写的模板文件。

因此,Jsoup将此模板文件视为无效的HTML文件。这就是所有非HTML元素都被转义的原因。

要获得所需内容,您必须编写自定义模板解析器。 Jsoup提供了一些通用的类,可以使这项任务变得非常简单。

但是,根据设计,这些通用类仅供内部使用。

这给我们留下了四个选择:

  • 您的实际解决方案
    使用纯HTML提取Jsoup
  • 向Jsoup团队发送issue
    要求能够创建自定义解析器
  • 编写更强大的自定义解析器
    这是一个重新发明的解决方案IMO
  • 更改(如果可行) 您当前的模板语言
    检查mustacheThymyleaf例如