我使用java的萨克斯类来解析XML文件。如果xml文件提到版本1.0,一切正常,但如果它说版本1.1,然后某些的属性会发生损坏,给我错误的结果,但不会抛出任何形式的异常。java萨克斯解析器mangles属性为XML 1.1
我的XML文件基本上是这样的:
<?xml version="1.1" encoding="UTF-8" ?>
<gpx>
<trk>
<name>Name of the track</name>
<trkseg>
<trkpt lat="12.3456789" lon="1.2345678">
<ele>1234</ele>
<time>2013-03-26T12:34:56Z</time>
<speed>0</speed>
</trkpt>
... and then 419 further identical copies of this trkpt
</trkseg>
</trk>
</gpx>
所以我希望,当我使用SAX解析这个文件,是要找到420个trkpt标签,并为他们每个人都有纬度和经度属性。特别是,我期望找到420“lat”属性,它们都是“12.3456789”。
对于解析我构造一个处理程序对象,并给它的流到此本地文件:
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
inStream = new FileInputStream(file);
saxParser.parse(inStream, handler);
System.out.println("done");
处理机类扩展org.xml.sax.helpers.DefaultHandler
,只是有一个方法,startElement
反作用于所述trkpt标签的开口:
public void startElement(String uri, String localName, String qName, Attributes attributes)
{
if (qName.equals("trkpt") && attributes != null
&& attributes.getLength() == 2
&& attributes.getValue(0).charAt(0) != '1')
{
// The trkpt tag has two attributes
// but the value of the first one doesn't begin with '1'
System.out.println(attributes.getQName(0) + " = " + attributes.getValue(0));
}
super.startElement(uri, localName, qName, attributes);
}
那么结果是什么? 如果xml文件的版本为1.0,那么我看到的只是“完成”。 420 trkpt标签被发现,他们都有两个属性,第一个总是被称为“lat”,并且这个属性的值总是以'1'开始,正如我所期望的。大!
如果XML文件更改为在第一行指定version="1.1"
,然后我得到以下输出:
lat = :34.56Z</t
lat = :56Z</time
done
所以,即使我所有的420点应该是相同的,他们两个给了我一个完全错误的属性值。没有例外被抛出。还有420 trkpts被发现,并且都有两个属性叫做“lat”和“lon”。奇怪的lon值总是没问题。
我在文本编辑器中通过直接复制/粘贴第一个trkpt创建了这个xml文件,所以我确信所有的值都是相同的,我确信xml文件中没有带有有趣属性值的点,并且我确信没有非ascii字符值或实体代码或其他关于该文件的奇怪内容。
我已经尝试过使用Sun的JRE6,OpenJDK6和OpenJDK7,在三个不同的机器上使用两个不同的操作系统。因此,无论我做错了什么,或者这个特定的xml文件与xml1.1不兼容,或者存在广泛的sax错误(这似乎不太可能,因为我认为它会影响很多人)。请再次注意,使用xml1.0它一切正常。另外请注意,420号没有什么特别之处,只是如果文件只有100个条目,那么它们都会被正确解析。如果您有几千个条目,那么其中一定数量的条目会以这种方式获得其第一个属性值。属性值的长度似乎总是正确的,但它将字符从文件中的错误位置拉出来。索引溢出也许?
我试着删除所有的速度标签,但如果您有足够的trkpts,问题仍然存在。它对额外的空格也很敏感,所以如果我在trkpt之间添加换行符,问题会发生在不同的点上,或者返回不同的属性值。
这可能是相关的:http://andrius.velykis。lt/2012/04/xml-11-long-attributes-in-java-6/ – 2013-03-26 10:35:46
听起来像是xml解析器中的一个bug,对于我来说,您使用的是哪个Java版本或哪个xml解析器?此外,属性的顺序不是由xml定义的,最好用'attributes.getValue(“lat”)'替换'attributes.getValue(0)'。 – 2013-03-26 10:40:20
正如我所说的,我正在使用JRE的内置sax解析,并且我尝试了Sun6,OpenJDK6和OpenJDK7。我不关心第一个属性是lat还是lon,它的值仍然应该以'1'开始。 – Penfold 2013-03-26 10:47:52