Java 报错:XML文档格式不正确。

7
Java的XML解析器似乎认为我的XML文档在根元素后面不是格式良好的。但我已经使用多个工具进行了验证,它们都不同意这一点。这可能是我的代码错误而不是文档本身的错误。如果您能提供任何帮助,我将不胜感激。
以下是我的Java方法:
private void loadFromXMLFile(File f) throws ParserConfigurationException, IOException, SAXException {
    File file = f;
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db;
    Document doc = null;
    db = dbf.newDocumentBuilder();
    doc = db.parse(file);
    doc.getDocumentElement().normalize();
    String desc = "";
    String due = "";
    String comment = "";
    NodeList tasksList = doc.getElementsByTagName("task");
    for (int i = 0; i  tasksList.getLength(); i++) {
        NodeList attributes = tasksList.item(i).getChildNodes();
        for (int j = 0; i < attributes.getLength(); j++) {
        Node attribute = attributes.item(i);
        if (attribute.getNodeName() == "description") {
            desc = attribute.getTextContent();
        }
        if (attribute.getNodeName() == "due") {
            due = attribute.getTextContent();
        }
        if (attribute.getNodeName() == "comment") {
            comment = attribute.getTextContent();
        }
        tasks.add(new Task(desc, due, comment));
        }
        desc = "";
        due = "";
        comment = "";
    }
}

以下是我尝试加载的XML文件:
<?xml version="1.0"?>  
<tasklist>  
    <task>  
        <description>Task 1</description>  
        <due>Due date 1</due>  
        <comment>Comment 1</comment>  
        <completed>false</completed>  
    </task>  
    <task>  
        <description>Task 2</description>  
        <due>Due date 2</due>  
        <comment>Comment 2</comment>  
        <completed>false</completed>  
    </task>  
    <task>  
        <description>Task 3</description>  
        <due>Due date 3</due>  
        <comment>Comment 3</comment>  
        <completed>true</completed>  
    </task>  
</tasklist>

以下是Java为我抛出的错误信息:

run:
[Fatal Error] tasks.xml:28:3: The markup in the document following the root element must be well-formed.
May 17, 2010 6:07:02 PM todolist.TodoListGUI <init>
SEVERE: null
org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed.
        at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:239)
        at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:283)
        at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:208)
        at todolist.TodoListGUI.loadFromXMLFile(TodoListGUI.java:199)
        at todolist.TodoListGUI.<init>(TodoListGUI.java:42)
        at todolist.Main.main(Main.java:25)
BUILD SUCCESSFUL (total time: 19 seconds)

参考TodoListGUI.java:199行

doc = db.parse(file);

如果有帮助的话,我正在尝试编写一个简单的GUI应用程序来管理任务清单,它可以读取和写入定义任务的XML文件。

你能发布一个XML文档的样例吗? - vtd-xml-author
您的 XML 标记似乎已经被吃掉了 - 您能否进行编辑以使它们可见?您应该能够使用 &lt; 得到 < - psmears
@psmears:不需要,只需使用4个空格进行缩进,或者选择代码,然后按编辑器工具栏中的“010101”按钮或“Ctrl+K”键。 - BalusC
你确定输入的是你所期望的吗? - Romain Hippeau
6个回答

12

org.xml.sax.SAXParseException: 文档根元素后的标记必须是格式良好的。

这个异常表示XML文档中有多个根元素。换句话说,<tasklist> 不是唯一的根元素。以您的XML文档为例,想象一下没有 <tasklist> 元素但在根部有三个 <task> 元素的情况,会导致此类异常。

由于您发布的XML文件看起来很正常,问题可能出现在其他地方。看起来它没有解析您预期要解析的XML文件。为了快速调试,请将以下内容添加到您的方法顶部:

System.out.println(f.getAbsolutePath());

在磁盘文件系统中定位该文件并验证。


4
我认为实际文件可能存在问题。当我复制您的代码但将XML作为字符串输入到解析器中时,它可以正常工作(在修复了一些问题后 - attributes.item(i) 应更改为 attributes.item(j),并且需要在 attribute == null 时退出循环)。
尝试重现您的错误时,如果我添加另一个 <tasklist></tasklist> 元素,我会得到相同的消息。这是因为XML不再具有单个根元素(tasklist)。这是您遇到的问题吗?tasks.xml 中的XML是否具有单个根元素?

1

尝试将您的XML声明更改为:

<?xml version="1.0" encoding="UTF-8" ?>

我只是提出“编码”建议,因为据我观察和测试,您已经拥有一个格式良好的XML文档……也许在您的代码中还有其他问题。 - EAMann
尝试了一下,但是没有得到任何结果。无论是否使用编码类型,它仍然给我相同的错误。 - Pyroclastic

0

就算不值得一提,Scala REPL 也成功解析了您的标记。

scala> val tree = <tasklist>
 | <task>
 | <description>Task 1</description>
 | <due>Due date 1</due>
 | <comment>Comment 1</comment>
 | <completed>false</completed>
 | </task>
 | <task>
 | <description>Task 2</description>
 | <due>Due date 2</due>
 | <comment>Comment 2</comment>
 | <completed>false</completed>
 | </task>
 | <task>
 | <description>Task 3</description>
 | <due>Due date 3</due>
 | <comment>Comment 3</comment>
 | <completed>true</completed>
 | </task>
 | </tasklist>
tree: scala.xml.Elem = 
<tasklist>
<task>
<description>Task 1</description>
<due>Due date 1</due>
<comment>Comment 1</comment>
<completed>false</completed>
</task>
<task>
<description>Task 2</description>
<due>Due date 2</due>
<comment>Comment 2</comment>
<completed>false</completed>
</task>
<task>
<description>Task 3</description>
<due>Due date 3</due>
<comment>Comment 3</comment>
<completed>true</completed>
</task>
</tasklist>

0

另外,就算价值而言,当我将你的XML保存到名为test.xml的文件中并通过xmllint运行它时,这是我得到的结果。

[jhr@Macintosh] [~]
xmllint test.xml
<?xml version="1.0"?>
<tasklist>  
    <task>  
        <description>Task 1</description>  
        <due>Due date 1</due>  
        <comment>Comment 1</comment>  
        <completed>false</completed>  
    </task>  
    <task>  
        <description>Task 2</description>  
        <due>Due date 2</due>  
        <comment>Comment 2</comment>  
        <completed>false</completed>  
    </task>  
    <task>  
        <description>Task 3</description>  
        <due>Due date 3</due>  
        <comment>Comment 3</comment>  
        <completed>true</completed>  
    </task>  
</tasklist>

看起来没问题。很可能你的实际文件中有一些你看不到的杂散字符。尝试在一个可以显示非打印字符的编辑器中查看实际文件,就像其他人建议的那样,如果这不是一个英语UTF-8机器,你可能有一些Unicode字符,解析器无法看到。或者你没有加载你认为的文件。在进入解析器之前,逐步调试并查看文件的实际内容。


0

你确定那个文件里没有别的内容了吗?错误提示里说当前根元素之后有更多的标记。所以 </tasklist> 之后必须还有其他的东西。

有时候,这种错误可能是由于不可打印字符引起的。如果你看不见什么,请对文件进行十六进制转储。


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