我使用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