【问题标题】:Parsing HTML Data using Java (DOM parse) [closed]使用 Java 解析 HTML 数据(DOM 解析)[关闭]
【发布时间】:2014-08-25 17:41:34
【问题描述】:

我已经为此工作了一段时间,但在 Stack Overflow 上没有找到任何相关内容。我正在使用一个旨在捕获 HTML 代码的 sn-ps 的解析器。根据代码(如下),文件的大小呈指数增长,并且正在捕获我需要的字段 (li),但也非常重复,因为它一遍又一遍地捕获相同的数据。

这是我正在读取的文件(完整的文件实际上有 100 多行,但这里只包含 3 行):

<html xlmns=http://www.w3.org/1999/xhtml>
<name>Name: J0719</name>
<bracket><description>Description: <ol><li>Hop Counts: 2</li><li>State: 3</li></eol></description></bracket> 
<name>Name: J0716</name>
<bracket><description>Description: <ol><li>Hop Counts: 3</li><li>State: 2</li></eol></description></bracket> 
<name>Name: J0718</name> 
<bracket><description>Description: <ol><li>Hop Counts: 1</li><li>State: 5</li></eol></description></bracket>
<name>Name: J0726</name>
<bracket><description>Description: <ol><li>Hop Counts: 8</li><li>State: 4</li></eol></description></bracket> 
</html>

我的完整代码在这里:

package ReadXMLFile_part2;

import java.io.*;

import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;


import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML.Tag;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;

public class ReadXMLFile_part2 {

public static void main(String[] args) throws Exception {

PrintStream out = new PrintStream(new FileOutputStream("C:/XML_UltraEdit/XML_Sandbox/NetBeans_Java_Project/results2.xml"));
System.setOut(out);

System.out.println("*** JSOUP ***");

File input = new File("C:/XML_UltraEdit/XML_Sandbox/NetBeans_Java_Project/output2_TEST.html");
Document doc = null;
    try {
        doc = Jsoup.parse(input,"UTF-8", "http://www.w3.org/1999/xhtml" );
    } catch (IOException ex) {
        Logger.getLogger(ReadXMLFile_part2.class.getName()).log(Level.SEVERE, null, ex);
    }
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

//For loops to capture the <li> fields in the file
Element bracket = doc.getElementsByTag("bracket").first();
Elements trs = bracket.getElementsByTag("description");
for (Element description : trs) {
    for (Element li : description.getAllElements()) {
        System.out.println(li.text());
    }
}
System.out.println();

//read a line from the console
String lineFromInput = in.readLine();

//output to the file a line
out.println(lineFromInput);                                 
out.close();    
}

}

我的问题是如何解析输入文件中标记为“li”的字段,以便我的输出文件中的每个“li”标签都有一个新行。理想的输出应该是这样的(并防止无限循环):

Name: J0719
Hop Counts: 2
State: 3
Name: J0716
Hop Counts: 3
State: 2
Name: J0718
Hop Counts: 1
State: 5
Name: J0726
Hop Counts: 8
State: 4

感谢并感谢您对此提供的任何帮助!

9 月 2 日更新: 虽然 previousElementSibling 单独使用时很有用,但是当我还尝试拉出“描述”字段时,我需要另一个嵌套循环(否则 previousElementSibling 每次都连续拉出第一个前一个元素)。我发现更快的解决方法是更改​​原始代码中的标签,使其现在看起来像下面的代码:

更新的 XML 文件:

<html xlmns=http://www.w3.org/1999/xhtml>
<bracket><li>Name: J0719</li>
<description>Description: <ol><li>Hop Counts 2</li><li>State: 3</li></eol></description></bracket>
<bracket><li>Name: J0716</li>
<description>Description: <ol><li>Hop Counts 3</li><li>State: 2</li></eol></description></bracket>
<bracket><li>Name: J0718</li>
<description>Description: <ol><li>Hop Counts 1</li><li>State: 5</li></eol></description></bracket>
<bracket><li>Name: J0719</li>
<description>Description: <ol><li>Hop Counts 8</li><li>State: 4</li></eol></description></bracket>
</html>

除了下面的“for”循环之外,原始代码中的其他所有内容都保持不变

//Updated Code:
//For loops to capture the (li) fields in the file
Elements brackets = doc.getElementsByTag("bracket");


    for (Element bracket : brackets) {
        Elements lis = bracket.select("li");

            for (Element li : lis){
                System.out.println(li.text());

        }
        break;
    }
    System.out.println();

唯一的另一件事是,在我看到文件大小停止增长后,我必须在执行后一段时间手动按下“停止”运行按钮。但我仍然看到输出文件产生了预期的结果。

【问题讨论】:

  • 你的问题是什么?
  • 感谢您抽出宝贵时间,我已将上述问题更新到最后。

标签: java html parsing dom jsoup


【解决方案1】:

如果我正确理解了您的问题,那么您的 xml 中的 namebracket 节点不是父节点的子节点,而只是一个接一个地出现。我认为当您拥有bracket 元素时获得正确的name 元素的解决方案是使用JSOUP's DOM navigation methods,即previousElementSibling()

您的循环如下所示:

Elements brackets = doc.getElementsByTag("bracket");
for (Element bracket : brackets) {
    Element lis = bracket.select("li");
    Element name = bracket.previousElementSibling();
    System.out.println(name.text());
    for (Element li : lis){
      System.out.println(li.text());
    }       
}

【讨论】:

  • 这很好!我最终根据 NetBeans 的建议稍微修改了它——谢谢!
  • 是的,上面的代码出乎我的意料。所以没有测试/语法检查
  • 跟进,previousElementSibling 在单独使用时很有用,但在尝试提取“描述”字段时,我需要另一个嵌套循环。我发现更快的解决方法是更改​​原始代码中的标签,使其现在看起来像上面更新的编辑中的代码。
  • 有没有办法使用 DOMParser 在 Java 中将 html 标签作为文本读取,否则,可能必须列出所有要处理的 html 标签?
  • @RohitKumar - 你可能想在 SO 上提出一个单独的问题来解决你的问题。
猜你喜欢
  • 2010-10-25
  • 1970-01-01
  • 2010-09-19
  • 2015-11-03
  • 2013-02-15
  • 2012-02-28
  • 2013-01-03
  • 1970-01-01
  • 2011-07-25
相关资源
最近更新 更多