我有一个大型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行中找到这个缺少的封闭元素。是否有一个我可以使用的工具可以建议可能存在问题的地方 - 例如在一定数量的行之后没有关闭的元素?
非常感谢任何想法。
答案 0 :(得分:8)
我使用Notepad++,它有一个出色的XML Tools插件,可让您检查XML语法并带您进入有问题的行。它也有实用的功能。
答案 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文件,它将查明故障的确切位置。