[英]Xml parsing with Python using recursion. Problem with return value
我對Python和一般編程還是有些陌生,所以我深表歉意。 順便說一句,在此先感謝。
我正在使用Python 2.5,cElementTree和expat解析xml文檔(專門用於Google Earth的kml)。 我試圖從每種幾何類型(即折線,多邊形,點)的每個“地標”節點中的“名稱”,“描述”和“坐標”節點中提取所有文本,但我想保留這些幾何類型分離。 例如,對於作為“多邊形”一部分(即它具有“多邊形”節點)的每個地標,我只需要“名稱”,“描述”和“坐標”文本。 我還需要針對“折線”和“點”執行此操作。 我已經找到了一種方法,但是代碼很冗長,並且特定於每種幾何類型,這導致了我的問題。
理想情況下,我想對每種幾何類型使用相同的代碼,但是問題是每種幾何類型具有不同的節點結構(即,不同的節點名稱和嵌套節點的數量)。 因此,為了概念驗證,我認為這將是使用/學習遞歸來深入研究“地標”節點的節點樹並獲取我正在尋找的信息的好機會。 我看過許多有關Python遞歸的文章,但在實現所提供的解決方案時仍然遇到問題。
“地標”節點的示例xml是:
<Placemark>
<name>testPolygon</name>
<description>polygon text</description>
<styleUrl>#msn_ylw-pushpin</styleUrl>
<Polygon>
<tessellate>1</tessellate>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-81.4065,31.5072,0 -81.41269,31.45992,0 -81.34490,31.459696,0
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
我正在使用的遞歸函數是:
def getCoords( child, searchNode ):
# Get children of node
children = child.getchildren()
# If node has one or more child
if len( children ) >= 1 :
# Loop through all the children
for child in children:
# call to recursion function
getCoords( child, searchNode )
# If does not have children and is the 'searchNode'
elif len( children ) == 0 and child.tag == searchNode:
# Return the text inside the node. This is where it is not working
# Other posts recommended returning the function like
# return getCoords(child, searchNode), but I am getting an unending loop
return child.text
# Do nothing if node doesn't have children and does not match 'searchNode'
else:
print 'node does not have children and is not what we are looking for'
我正在調用遞歸函數,如:
searchNode = 'coordinates'
# loop through all 'Placemark nodes' in document
for mark in placemark:
# Get children of 'Placemark' node
children = mark.getchildren()
# Loop through children nodes
for child in children:
# if a 'Polygon' node is found
if child.tag == 'Polygon':
# call recursion function
getCoords( child, searchNode)
我至少知道部分問題是返回值。 其他帖子建議返回該函數,我將其解釋為“返回getCoords(child,searchNode),但我遇到了無休止的循環。 另外,我意識到這可以發布在GIS網站上,但是我認為這更多是一個通用的編程問題。 有任何想法嗎?
使用遞歸時,您要注意基本情況和遞歸情況。 無論您遇到的基本案例是什么,如果您希望能夠從遞歸中收集信息,則它們必須返回遞歸案例可以(並且更重要的是可以使用)的數據。 同樣,您需要確保遞歸案例返回的數據可以相互使用。
首先確定您的基礎案例和遞歸案例。 基本情況是“葉”節點,沒有子節點。 在基本情況下,您只想返回一些數據,而不要再次調用遞歸函數。 這就是使您能夠像他們所說的那樣“備份堆棧”並防止無限遞歸的方法。 遞歸情況將需要您保存從一系列遞歸調用中收集的數據,這幾乎是您在for
循環中所做的事情。
我注意到你有
# Recursive case: node has one or more child
if len( children ) >= 1 :
# Loop through all the children
for child in children:
# call to recursion function
getCoords( child, searchNode )
但是您如何處理getCoords調用的結果?
您或者希望將結果保存在某種數據結構中,然后可以在for循環結束時返回,或者如果您對保存結果本身不感興趣,只需在出現以下情況時打印基本情況1(成功搜索):您到達它而不是返回它。 因為現在您的基本情況1只是將堆棧返回到對結果不做任何事的實例! 因此,請嘗試:
# If node has one or more child
if len( children ) >= 1 :
# Data structure for your results
coords = []
# Loop through all the children
for child in children:
# call to recursion function
result = getCoords( child, searchNode )
# Add your new results together
coords.extend(result)
# Give the next instance up the stack your results!
return coords
現在,由於您的結果在列表中,並且使用了extend()
方法,因此還必須使基本案例也返回列表!
# Base case 1: does not have children and is the 'searchNode'
elif len( children ) == 0 and child.tag == searchNode:
# Return the text from the node, inside a list
return [child.text]
# Base case 2: doesn't have children and does not match 'searchNode'
else:
# Return empty list so your extend() function knows what to do with the result
return []
最后應該只給您一個列表,您可能希望將其存儲在變量中。 我剛剛在這里打印了結果:
searchNode = 'coordinates'
# loop through all 'Placemark nodes' in document
for mark in placemark:
# Get children of 'Placemark' node
children = mark.getchildren()
# I imagine that getchildren() might return None, so check it
# otherwise you'll get an error when trying to iterate on it
if children:
# Loop through children nodes
for child in children:
# if a 'Polygon' node is found
if child.tag == 'Polygon':
# call recursion function and print (or save) result
print getCoords( child, searchNode)
當節點是searchNode時,您對遞歸調用的結果不做任何事情。
您需要聚合對節點子節點的遞歸調用的結果,或者只使用print child.text而不是return child.text。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.