我正在尝试使用javax.xml.stream.XMLStreamReader
解析(相当大)的XML文件。文件格式正确(使用xmllint验证),但我仍然得到以下异常:
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[12418,95]
Message: XML document structures must start and end within the same entity.
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:592)
这是我的代码的简化:
while(parser.hasNext()){
parser.next();
if (parser.getEventType() == XMLStreamReader.START_ELEMENT){
if (parser.getLocalName() == "s") {
// do stuff
}
}
if (parser.getEventType() == XMLStreamReader.END_ELEMENT){
if (parser.getLocalName() == "s") {
// do more stuff
}
}
if (parser.getEventType() == XMLStreamReader.CHARACTERS){
if (inSentenceElement) {
// process text
parser.getText()...
}
}
}
我已经检查了错误消息中给出的XML中的行/列,没有什么让我觉得异常。我一直在想文件的大小可能是一个问题,它们会被截断,以便在根元素关闭之前读取EOF。这是可行的,如果是的话,我该如何避免呢?
编辑:bz2-zipped文件最大为1.5G,最多7M行,但在大约10K行后4M崩溃的文件相对较小(尽管出现问题后的行数往往会因一些3K线。
答案 0 :(得分:1)
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,4207737]
Message: Attribute name "i" associated with an element type "someElement" must be followed by the ' = ' character.
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:598)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:181)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:355)
... 49 more
实际XML中的属性是:index =" 1",所以它有效,但它被截断或其他东西。相同的代码和XML与Java 1.7.0u51一起使用,但是由于1.7.0u71的上述异常而失败。位置始终与该文件位于同一列(CharacterOffset = 4207736)。我正在使用JAXB,它在解组时调用它,但除了Java版本之外没有任何改变。
我建议检查最近添加的一些新的XML限制,以减少拒绝服务攻击,它确实适用于我的情况。 https://docs.oracle.com/javase/tutorial/jaxp/limits/using.html
具体来说,在运行的命令行中添加以下内容将禁用所有这些操作。我强烈建议找出更好的限制(或导致问题的特定限制),而不是用0来全部关闭。
java -Djdk.xml.entityExpansionLimit=0 -Djdk.xml.elementAttributeLimit=0 -Djdk.xml.maxOccurLimit=0 -Djdk.xml.totalEntitySizeLimit=0 -Djdk.xml.maxGeneralEntitySizeLimit=0 -Djdk.xml.maxParameterEntitySizeLimit=0 -Djdk.xml.maxElementDepth=0 -jar myJarfile.jar