使用Java将HTML转换为树

a22*_*sin 3 html java arrays tree parsing

所以我试图编写一个程序,它将包含简单HTML语法的文件放入一个树中,该树将显示标签的层次结构.最终,每个叶子将包含一个标签(即p,h,ul等)和文本.这很简单,我打算使用Jtree来显示最终输出.但是,我遇到的困难是通过语法并使用标记构建初始树而不会丢失关系.我认为整个文件将是一个长字符串.该程序将找到一个'<',其中第二个字符不是'/',并考虑一个新的标签/叶子.然后代码将继续并检查下一组字符,以查看是否有另一个'<'表示子标记.如果在'<'之后的第二个字符中找到'/',则代码将移动到同一级别的下一个叶子.

希望你能得到我想要做的事情,不幸的是,我的尝试不太成功,因为它只显示了根标签的子节点.目前,我只是试图让标签在树中工作,文本和我以后不能弄清楚的.为了测试代码,我使用了一个"test"包含一些基本示例html代码的字符串,每个节点都在创建jtree时显示在根目录中,但node2中的子节点从不显示.我很困惑,不能在这周围饶舌.另外,有更简单/有效的方法吗?

**编辑:所以我修改了使用JSoup工作的代码.我设法让它工作,但是,我有一个问题,由于某种原因,除了标签的第一个子标签之外的所有head标签都被移动了body.所以现在body有3个孩子而不是1个,head只有一个而不是三个.另外,我如何修改getChildren()递归函数以适应前一个子节点中的每个子图层?例如,要在h3标记内获取title标记?

package weboqltree_converter;

import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
import java.util.ArrayList;
import java.awt.Dimension;
import java.util.List;
import javax.swing.tree.TreeNode;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Node;

public class GUI extends JFrame
{
    private JTree tree;
    private String test = "<html>"
            +   "<head>"
            +       "<title><h3>First parse<h3></title>"
            +       "<a></a>"
            +       "<h3></h3>"
            +   "</head>"
            +   "<body>"
            +       "<p>Parsed HTML into a doc.</p>"
            +   "</body>"
            + "</html>";

    private int parentNode;

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new GUI();
            }
        });
    }

    public GUI()
    {
        DefaultMutableTreeNode html = new DefaultMutableTreeNode("html");
        Document doc = Jsoup.parse(test);
        int children = doc.childNodes().get(0).childNodes().size();
        for(int i=0; i < children; i++){
            String tag = doc.childNodes().get(0).childNodes().get(i).nodeName();
            String text = "N/A"; //doc.childNodes().get(0).childNodes().get(i).toString();

            html.add(new DefaultMutableTreeNode("Tag: " + tag+ ", Text: " + text));

            System.out.println(tag+" : "+doc.childNodes().get(0).childNodes().get(i).childNodeSize());

            if(doc.childNodes().get(0).childNodes().get(i).childNodeSize() > 0){
                getChildren(html.getLastLeaf(), doc.childNodes().get(0).childNodes().get(i),0, doc.childNodes().get(0).childNodes().get(i).childNodeSize());
            }
        }
        System.out.println("tag: " + children);           


        //System.out.println(Tree.get(2) +" "+Tree.get(2).getChildCount());
        tree = new JTree(html);
        add(tree);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("JTree Example"); 
        this.setMinimumSize(new Dimension(300, 400));
        this.setExtendedState(3);
        this.pack();
        this.setVisible(true);
    }

    public void getChildren(DefaultMutableTreeNode tree, Node doc, int start, int size){

        tree.add(new DefaultMutableTreeNode("Tag: " + doc.childNodes().get(start).nodeName()));
        start++;

        if(start < size){
            getChildren(tree, doc, start, size);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*fan 5

你可以使用JSoup来做到这一点.它读取一个String,一个文件或URL并将其解析为一个Document对象(它的速度非常快).之后,您可以导航对象并从中创建JTree.

String html = "<html><head><title>First parse</title></head><body><p>Parsed HTML into a doc.</p></body></html>";
Document document = Jsoup.parse(html);
Run Code Online (Sandbox Code Playgroud)

更新

我已将您的代码更改为使用递归方法.因为文档中可能有多个根节点(通常是"document"-tag和"html"-tag),所以最好添加一个默认的根节点.看一看:

public GUI() {
    // create window
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setTitle("JTree Example");
    this.setMinimumSize(new Dimension(300, 400));
    this.setExtendedState(3);

    // create tree and root node
    this.tree = new JTree();
    final DefaultMutableTreeNode ROOT = new DefaultMutableTreeNode("Html Document");

    // create model
    DefaultTreeModel treeModel = new DefaultTreeModel(ROOT);
    tree.setModel(treeModel);

    // add scrolling tree to window
    this.add(new JScrollPane(tree));

    // parse document (can be cleaned too)
    Document doc = Jsoup.parse(test);
    // Cleaner cleaner = new Cleaner(Whitelist.simpleText());
    // doc = cleaner.clean(doc);

    // walk the document tree recursivly
    traverseRecursivly(doc.getAllElements().first(), ROOT);

    this.expandAllNodes(tree);
    this.pack();
    this.setLocationRelativeTo(null);
    this.setVisible(true);
}

private void traverseRecursivly(Node docNode, DefaultMutableTreeNode treeNode) {
    // iterate child nodes:
    for (Node nextChildDocNode : docNode.childNodes()) {
        // create leaf:
        DefaultMutableTreeNode nextChildTreeNode = new DefaultMutableTreeNode(nextChildDocNode.nodeName());
        // add child to tree:
        treeNode.add(nextChildTreeNode);
        // do the same for this child's child nodes:
        traverseRecursivly(nextChildDocNode, nextChildTreeNode);
    }
}

// can be removed ...
private void expandAllNodes(JTree tree) {
    int j = tree.getRowCount();
    int i = 0;
    while (i < j) {
        tree.expandRow(i);
        i += 1;
        j = tree.getRowCount();
    }
}
Run Code Online (Sandbox Code Playgroud)