使用document.getElementById无法获得元素,返回null。

4

我正在尝试从文件中获取一个HTML节点,以后将用于计算其所有后代数。 我在检索DOM中的元素时遇到了问题。以下是我迄今为止采取的步骤:

首先这是我的HTML代码:

<html>
<head>
    <title></title>
</head>
<body>
<div id="container">
    <a></a>
    <div id="header">
        <div id="firstchild">
            <div>
                <img></img>
            </div>
            <a></a>
            <ul>
                <li>
                    <a>Inbox</a>
                </li>
                <li>
                    <a>Logout</a>
                </li>
            </ul>
            <form></form>
        </div>
        <div id="nextsibling"></div>
    </div>
</div>
</body>
</html>

第二步,我构建了这个函数,它将返回并解析文件为一个文档。
public static Document buildDocument(String file){
    try {
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        Document document = docBuilder.parse(file);
        return document;
    } catch (ParserConfigurationException | SAXException | IOException ex) {
        System.out.println("the exception is: " + ex.toString());
    }
    return null;
}

在我的主方法中,我尝试通过getElementById方式将一个Node对象设置为文档元素,如下所示:

public Document doc = buildDocument("myHTMLFile");
org.w3c.dom.Node node = doc.getElementById("header");//the id of an html element

如果我说错了,请纠正我,但这应该会导致检索节点。然而,它返回了一个null值。我不明白为什么它没有返回正确的值。注意:调试代码时,据我所知,文档包含所有正确的数据。


你能否在catch中添加一个更通用的异常?(顺便说一下,我不是Java专家) - Brett Zamir
还有,你传递的是"myHTMLFile"吗?我假设它有一个扩展名或者parse方法需要获取其内容而不是将其解释为字符串? - Brett Zamir
我认为错误不在于构建文档函数。当我逐步执行程序时,我能够查看文档并看到其中的所有元素。似乎当调用getElementById时,它无法找到该ID,但我知道它存在,所以我不知道为什么它找不到它。 - Jared Reeves
@brett,是的,那就是扩展名,我为了这个问题而将其存根。 - Jared Reeves
3个回答

11

你做错了。getElementById的javadoc说:

返回具有给定值的ID属性的元素。如果不存在这样的元素,则返回null。... DOM实现应使用Attr.isId属性来确定属性是否为ID类型。 注意:除非明确定义,否则名称为“ID”或“id”的属性不属于ID类型。

在你的情况下,最好的解决方案是使用XPath(用于XML的简单查询语言):

XPath xpath = XPathFactory.newInstance().newXPath();
Node node = (Node) xpath.evaluate("//*[@id='header']", document, XPathConstants.NODE);

表达式 //*[@id='header'] - 选择文档中所有具有属性id且值为'header'的节点。


谢谢,太棒了!一旦我能够获取元素,我的代码的其余部分就完美地运行了。 - Jared Reeves
1
哇,这个API太愚蠢了。很明显,属性ID就是大家所说的ID... - Vistritium

4

看起来您正在使用通用的XML DOM。XML希望将ID定义为此类,因此具有属性的元素(即使命名为"id")也无法正常工作,除非它被指定为此类。

尝试找到特定于HTML的接口或添加一个DOCTYPE,该DOCTYPE将id属性定义为ID类型。(虽然技术上支持XHTML序列化,但我不建议后者,因为HTML5已经摆脱了尝试与XHTML兼容的方法。)请参见使用JAVA解析网站HTML,以获取有关HTML特定解析器的推荐。


-2

尝试做以下两件事情:

  1. 在你的buildDocument()函数中,添加以下代码:

      Element element = document.getDocumentElement();
    
  2. 将函数的返回类型更改为“Element”,并返回“element”

  3. 创建一个“Element”对象而不是“Document”对象,并在其上调用“getElementById()”。
  4. 还要检查文件名,如果缺少“.html”扩展名

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接