2012-08-04 42 views
1

我在學習運行Python 2.7.2的XML處理(使用lxml)的基礎知識。我已經創建了一個非常簡單的開始文件,但是它很糟糕。的代碼是:在Python中使用xml.etree解析xml代碼時出錯

from lxml import etree 

doc = etree.parse('/Desktop/plc_dmt.xml') 

print doc 

我試圖對這個代碼變型中,使用不同的XML文件,並且還執行調用etree.parse()方法之前首先打開文件,但是它們都得到相似或相同的錯誤消息,如下:

Traceback (most recent call last): 
    File "XMLparse_test.py", line 7, in <module> 
    doc = etree.parse('/Users/Dad/Desktop/plc_dmt.xml') 
    File "lxml.etree.pyx", line 2954, in lxml.etree.parse (src/lxml/lxml.etree.c:56220) 
... {Misc error stuff} 
... 
    lxml.etree.XMLSyntaxError: xmlParsePI : no target name, line 3, column 14 

我證實,至少有一些XML文件進行了良好的,至少因爲它們在Web服務器上正確運行。我不明白錯誤消息 - 它正在尋找的目標名稱是什麼?

這裏是輸入xml文件。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<response> 
<heartbeat><?--#exec cmd_argument='printf("0x%02X%02X", InReadUByte(0), InReadUByte(1))'--> </heartbeat> 

<dmt node="1"> 
    <address><?--#exec cmd_argument='printf("0x%02X", InReadUByte(20))'--></address> 
    <status><?--#exec cmd_argument='printf("0x%02X", InReadUByte(21))'--></status> 
    <realflow><?--#exec cmd_argument='printf("%f", InReadFloat(22))'--></realflow> 
    <pressure><?--#exec cmd_argument='printf("0x%02X%02X", InReadUByte(26), InReadUByte(27))'--></pressure> 
    <temp><?--#exec cmd_argument='printf("0x%02X%02X", InReadUByte(28), InReadUByte(29))'--></temp> 
</dmt> 
# Misc stuff pulled out to keep file shorter... 
</response> 

大部分的嵌入代碼都是服務器端包含此Web服務器連接到一些儀器的命令。該文件在服務器上運行正常。

+1

請將xml貼出。我們需要看到它 – 2012-08-04 19:13:15

+0

@只是另一個傻瓜:我已經添加了上面原始帖子的摘錄。 – 2012-08-04 19:32:55

+0

將XML傳遞給http://www.xmlvalidation.com表示它不是有效的XML。在第3行第14列,「處理指令必須以目標名稱開始。」 – unutbu 2012-08-04 19:46:11

回答

0

您的XML無效,因爲您的元素中有<>個字符。他們必須逃脫。

如果他們實際上應該是註釋,這是它應該是什麼:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<response> 
<heartbeat><!--#exec cmd_argument='printf("0x%02X%02X", InReadUByte(0), InReadUByte(1))'--> </heartbeat> 

<dmt node="1"> 
    <address><!--#exec cmd_argument='printf("0x%02X", InReadUByte(20))'--></address> 
    <status><!--#exec cmd_argument='printf("0x%02X", InReadUByte(21))'--></status> 
    <realflow><!--#exec cmd_argument='printf("%f", InReadFloat(22))'--></realflow> 
    <pressure><!--#exec cmd_argument='printf("0x%02X%02X", InReadUByte(26), InReadUByte(27))'--></pressure> 
    <temp><!--#exec cmd_argument='printf("0x%02X%02X", InReadUByte(28), InReadUByte(29))'--></temp> 
</dmt> 
</response> 

如果實際上應該是文本,那麼他們需要進行轉義,像這樣:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<response> 
<heartbeat>&lt;?--#exec cmd_argument='printf("0x%02X%02X", InReadUByte(0), InReadUByte(1))'--&gt; </heartbeat> 

<dmt node="1"> 
    <address>&lt;?--#exec cmd_argument='printf("0x%02X", InReadUByte(20))'--&gt;</address> 
    <status>&lt;?--#exec cmd_argument='printf("0x%02X", InReadUByte(21))'--&gt;</status> 
    <realflow>&lt;?--#exec cmd_argument='printf("%f", InReadFloat(22))'--&gt;</realflow> 
    <pressure>&lt;?--#exec cmd_argument='printf("0x%02X%02X", InReadUByte(26), InReadUByte(27))'--&gt;</pressure> 
    <temp>&lt;?--#exec cmd_argument='printf("0x%02X%02X", InReadUByte(28), InReadUByte(29))'--&gt;</temp> 
</dmt> 
</response> 

上述兩個文件都是有效的。

+0

謝謝,這非常有趣,因爲嵌入在xml中的服務器端包含命令具有非常特定的格式要求。我會深入探討,並將結果記錄回來。 – 2012-08-04 21:39:37

+0

[apache ssi](http://httpd.apache.org/docs/current/howto/ssi.html)?如果是這樣,它應該是''''''不''''' – jterrace 2012-08-04 22:00:48

+0

實際上,我不知道使用哪種SSI風味,這是一個供應商特定的設備,用於連接到他們自己的化學過程儀器,它不是「通用」服務器。文檔明確指出'?',但不是'!'。我使用第二個建議調整了代碼示例,使用@unutbu建議的xmlvalidation.com網站確認格式良好的文檔,並且lxml.etree代碼示例沒有拋出異常,但添加了一個額外的'>'以當我使用'tostring'時輸出。我還想檢查的一件事是實際上在SSI服務器上運行調整過的代碼。 – 2012-08-05 00:52:47