2013-10-16 29 views
2

我需要一些幫助。我有這個XML:如何使用python從xml文件獲取值

<?xml version="1.0"?> 
<WDAT> 
<EMOD> 
     <MATERIAL number="1.2345"> 
      <Values> 
         <X>20.0</X> 
         <Y>200.0</Y> 
      </Values> 
      <Values> 
         <X>100.0</X> 
         <Y>190.0</Y> 
      </Values> 
      <Values> 
         <X>200.0</X> 
         <Y>185.0</Y> 
      </Values> 
      <Values> 
         <X>300.0</X> 
         <Y>180.0</Y> 
      </Values> 
      <Values> 
         <X>400.0</X> 
         <Y>175.0</Y> 
      </Values> 
    </MATERIAL> 
</EMOD> 
</WDAT> 

例如,我想獲得一個數組,其材料號爲1.2345的X-Y值。

tree_materials = ET.parse(r"materials.xml") 
root_materials = tree_materials.getroot() 
materials = root_materials.findall('EMOD/MATERIAL') 
material = tree_materials.findall(".//MATERIAL[@number='1.2345']") 
valuess = material.findall('X') 

變量「材料」具有正確的內存地址,但我有困難得到X和Y

感謝值。

拉斐爾

回答

1

在'MATERIAL'下面,你有兩個級別 - 所以你需要通過兩個級別findall。你可以這樣做:

material = tree_materials.find(".//MATERIAL[@number='1.2345']") 
lx = material.findall('Values/X') 
ly = material.findall('Values/Y') 
points = zip([x.text for x in lx], [y.text for y in ly]) 

但是,你真的相信你的XML來做到這一點 - 如果有人不小心給你這樣一個文件:

 <Values> 
        <X>200.0</X> 
        <Y>185.0</Y> 
     </Values> 
     <Values> 
        <Y>180.0</Y> 
     </Values> 
     <Values> 
        <X>400.0</X> 
        <Y>175.0</Y> 
     </Values> 

,那麼你最終會與(200.0, 185.0), (180.0, 175.0)和自拉鍊停在最短的項目上,400.0會被悄悄放下,你甚至可能不知道。 明確更好:

values = material.findall('Values') 
points = [(v.find('X').text, v.find('Y').text) for v in values] 

如果X或Y節點不存在,這將拋出一個異常,你會馬上看到它。

你需要做另一個列表理解來將它們轉換爲浮點,但你已經可以做到這一點。

+0

謝謝,好點! – user2886173

1

在最後2行,你可以做到以下幾點:

material = tree_materials.find(".//MATERIAL[@number='1.2345']") 
    xs = material.findall('X') 
    ys = material.findall('Y') 
    values = zip([x.text for x in xs], [x.text for x in xs]) 

這將輸出元組的像列表[( 「20.0」, 「200.0」)...]

+0

感謝您的快速回答。我檢查了「材質」的內存地址,沒關係。但是在最後一行中出現錯誤:KeyError:'()' – user2886173

+0

我做了一個編輯。我的代碼出錯了。 –

+0

我現在得到「AttributeError:'list'object has no attribute'text'」。我接近解決方案,但我不明白爲什麼不工作。我知道,它一定很容易......我在學習。謝謝。 – user2886173

0
material = tree_materials.xpath("//MATERIAL[@number='1.2345']")[0] 
x_values = [x.text for x in material.xpath("//X")] 
y_values = [y.text for y in material.xpath("//Y")] 
xy_values = zip(x_values, y_values)