使用Java解析HTML数据(DOM解析)

我已经研究了一段时间,并没有找到任何与Stack Overflow相关的东西。 我正在使用一个旨在捕获HTML代码片段的解析器。 基于代码(下面进一步说明),文件的大小呈指数级增长并且正在捕获我需要的字段(li),但也是非常重复的,因为它一遍又一遍地捕获相同的数据。

这是我正在阅读的文件(完整文件实际上有超过100行但这里只包括3行):

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

我的完整代码在这里:

 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 
  • 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文件:

      
  • Name: J0719
  • Description:
    1. Hop Counts 2
    2. State: 3
    3. Name: J0716
    4. Description:
      1. Hop Counts 3
      2. State: 2
      3. Name: J0718
      4. Description:
        1. Hop Counts 1
        2. State: 5
        3. Name: J0719
        4. Description:
          1. Hop Counts 8
          2. State: 4

    除了以下’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(); 

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

    如果我正确地理解了您的问题,那么您就难以理解xml中的namebracket节点不是父节点的子节点,而是相互追随。 我认为在拥有bracket元素时获取正确name元素的解决方案是使用JSOUP的DOM导航方法 ,即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()); } }