无法在XML中找到未关闭的元素

时间:2011-04-03 23:57:31

标签: xml

我有一个大型XML文件(~18MB)。显然,其中有一个标签没有关闭。我知道这是因为当我运行W3C标记验证工具(validator.w3.org)时,我收到以下错误:

You may have neglected to close an element, or perhaps you meant to "self-close" an element, that is, ending it with "/>" instead of ">".

我的问题是如何在文件中的500,000行中找到这个缺少的封闭元素。是否有一个我可以使用的工具可以建议可能存在问题的地方 - 例如在一定数量的行之后没有关闭的元素?

非常感谢任何想法。

5 个答案:

答案 0 :(得分:8)

我使用Notepad++,它有一个出色的XML Tools插件,可让您检查XML语法并带您进入有问题的行。它也有实用的功能。

enter image description here

答案 1 :(得分:4)

xmllint是此标准工具。来自Validation & DTDs页面:

  

最简单的方法是使用libxml附带的xmllint程序。 --valid选项打开作为输入提供的文件的验证。例如,以下验证XML 1.0规范的第一个修订版的副本:

xmllint --valid --noout test/valid/REC-xml-19980210.xml
  

- noout用于禁用结果树的输出。

     

--dtdvalid dtd允许针对给定的DTD验证文档。

     

Libxml2导出一个API来处理DTD和验证,检查相关的描述。

如果您的文档没有“漂亮打印”,那么仍然很难找到有问题的节点,因此您可能希望使用xmllint来重写要缩进的文件。

答案 2 :(得分:3)

我刚刚在VS 2010中打开了一个XML文件(使用ReSharper),打破了XML,你知道什么?错误立即突出显示。如果您可以访问相同的内容,就这么简单。

答案 3 :(得分:0)

由于您没有XML Schema,因此找不到有问题的代码没有万无一失的方法,例如XML允许递归结构。但是你可以编写自己的XML Schema,尽管这可能需要学习很多东西。或者,我会创建一个简单的,愚蠢的节点级别验证器和元素名称,如下所示:

private void parseAndCheckStructure(XMLStreamReader reader) throws XMLStreamException {

    // first read header, this is probably not the offending element (?)
    int event = -1;
    while (reader.hasNext()) {
        event = reader.next();
        if (event == XMLStreamConstants.START_ELEMENT){
            break;
        } else if (event == XMLStreamConstants.END_DOCUMENT) {
            throw new XMLStreamException();
        }
    }

    // read the rest of the document.
    int level = 1;
    do {
        event = reader.next();
        if (event == XMLStreamConstants.START_ELEMENT){
            level++;
            String localName = reader.getLocalName();
            if(localName.equals("FirstElement")) {
                parseFirstElementWithALoopLikeTheCurrent(reader);

                level--;
            } else if(localName.equals("SecondElement")) {
                parseSecondElementWithALoopLikeTheCurrent(reader);

                level--;

            } else throw new RuntimeException("Unknown element " + localName + " at level " + level + " and location " + reader.getLocation());

        } else if(event == XMLStreamConstants.END_ELEMENT) {
            // keep track of level
            level--;
        }
    } while(level > 0);

}

或者,在上面的do-while循环中解析整个文档,并进行类似

的检查
if(level == 4 && localName.equals("MyElement")) {
    // ok
} else {
    // throw exception with the location
}

很糟糕,但确实有效。

答案 4 :(得分:0)

尝试使用chrome浏览器打开.xml文件,它将查明故障的确切位置。