如何只将 <body> 标签内的文本内容加载到 JTextPane 中?

How to only load text contents into JTextPane that are within the <body> tags?

现在,我在 Java Swing 中有一个 JTextPane 可以将文件中的内容加载到窗格中。但是,它会加载所有内容,包括所有标签。我希望它只加载内容。有没有办法获取标签并加载 <body></body> 之间的部分?

这是代码

public class LoadContent {

String path = "../WordProcessor_MadeInSwing/backups/testDir/cool_COPY3.rtf";

public void load(JTextPane jTextPane){
    try {
        FileReader fr = new FileReader(path);
        BufferedReader reader = new BufferedReader(fr);
        jTextPane.read(reader, path);

    } catch (FileNotFoundException ex) {
        ex.printStackTrace();
    }
    catch(IOException e){

    }
}

}

如果我的 .rtf 文件包含单词 "Here is a test",它将加载为:

<html>
  <head>
    <style>
      <!--
        p.default {
          family:Dialog;
          size:3;
          bold:normal;
          italic:;
          foreground:#333333;
        }
      -->
    </style>
  </head>
  <body>
    <p class=default>
      <span style="color: #333333; font-size: 12pt; font-family: Dialog">
        Here is a test
      </span>
    </p>
  </body>
</html>

我只想加载它"Here is a test"

I would like it to only load the contents

那么在显示文字之前需要先解析出内容

这是一个显示 Span 标签之间文本的简单示例:

import java.io.*;
import java.net.*;
import javax.swing.text.*;
import javax.swing.text.html.*;

class GetSpan
{
    public static void main(String[] args)
        throws Exception
    {
        // Create a reader on the HTML content

        Reader reader = getReader( args[0] );

        // Parse the HTML

        EditorKit kit = new HTMLEditorKit();
        HTMLDocument doc = (HTMLDocument)kit.createDefaultDocument();
        doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE);
        kit.read(reader, doc, 0);

        // Find all the Span elements in the HTML document

        HTMLDocument.Iterator it = doc.getIterator(HTML.Tag.SPAN);

        while (it.isValid())
        {
            int start = it.getStartOffset();
            int end = it.getEndOffset();
            String text = doc.getText(start, end - start);
            System.out.println(  text );
            it.next();
        }
    }

    // If 'uri' begins with "http:" treat as a URL,
    // otherwise, treat as a local file.
    static Reader getReader(String uri)
        throws IOException
    {
        // Retrieve from Internet.
        if (uri.startsWith("http"))
        {
            URLConnection conn = new URL(uri).openConnection();
            return new InputStreamReader(conn.getInputStream());
        }
        // Retrieve from file.
        else
        {
            return new FileReader(uri);
        }
    }
}

只是 运行 class 以您的文件作为参数。

编辑:

刚刚注意到问题已更改为在 <body> 标签而不是 <span> 标签中查找文本。由于某种原因,<body> 标记没有返回迭代器。

所以另一种选择是使用 ParserCallback。每次找到开始标记(或结束标记)或找到任何标记的文本时,回调都会通知您。

一个基本的例子是:

import java.io.*;
import java.net.*;
import javax.swing.text.*;
import javax.swing.text.html.parser.*;
import javax.swing.text.html.*;

public class ParserCallbackText extends HTMLEditorKit.ParserCallback
{
    private boolean isBody = false;

    public void handleText(char[] data, int pos)
    {
        if (isBody)
            System.out.println( data );
    }

    public void handleStartTag(HTML.Tag tag, MutableAttributeSet a, int pos)
    {
        if (tag.equals(HTML.Tag.BODY))
        {
            isBody = true;
        }
    }

    public static void main(String[] args)
        throws Exception
    {
        Reader reader = getReader(args[0]);
        ParserCallbackText parser = new ParserCallbackText();
        new ParserDelegator().parse(reader, parser, true);
    }

    static Reader getReader(String uri)
        throws IOException
    {
        // Retrieve from Internet.
        if (uri.startsWith("http"))
        {
            URLConnection conn = new URL(uri).openConnection();
            return new InputStreamReader(conn.getInputStream());
        }
        // Retrieve from file.
        else
        {
            return new FileReader(uri);
        }
    }
}

以上示例将忽略找到 <head> 标签的任何文本。

尝试使用 HTML 解析器。 jsoup 不错,而且非常容易使用。

  public static String extractText(Reader reader) throws IOException {
    StringBuilder sb = new StringBuilder();
    BufferedReader br = new BufferedReader(reader);
    String line;
    while ( (line=br.readLine()) != null) {
      sb.append(line);
    }
    String textOnly = Jsoup.parse(sb.toString()).text();
    return textOnly;
  }