2016-04-22 151 views
-3

如何修改下面的XML片段與Python腳本修改XML文件

<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/routes_file.xsd"> 
    <vType id="car1_73" length="4.70" minGap="1.00" maxSpeed="12.76" probability="0.00" vClass="passenger" guiShape="passenger/van"> 
     <carFollowing-Krauss accel="2.40" decel="4.00" sigma="0.55"/> 
    </vType> 
    <vehicle id="0" type="vTypeDist" depart="0.00" departLane="best" departPos="random" departSpeed="random"> 
     <routeDistribution last="1"> 
      <route cost="108.41" probability="0.44076116" edges="bottom7to7/0 7/0to6/0 6/0to6/1 6/1to5/1 5/1to5/2 5/2to6/2"/> 
      <route cost="76.56" probability="0.55923884" edges="bottom7to7/0 7/0to6/0 6/0to5/0 5/0to5/1 5/1to5/2 5/2to6/2"/> 
     </routeDistribution> 
    </vehicle> 
</routes> 

使得得到一個看起來是這樣的:

<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/routes_file.xsd"> 
    <vehicle id="0" type="vTypeDist" depart="0.00" departLane="best" departPos="random" departSpeed="random"> 
     <route edges="bottom7to7/0 7/0to6/0 6/0to5/0 5/0to5/1 5/1to5/2 5/2to6/2"/> 
    </vehicle> 
</routes> 

基本上下面已經做

  • 完全刪除<vtype>(和<carFollowing...>元素),
  • 刪除<routeDistribution...>
  • 創建<route>元素只能保存最後edges屬性從<routeDistribution...>元素中。

編輯:在這裏,我提供使用xml.etree.ElementTree我的版本。爲什麼所有的downvotes雖然...:/

import xml.etree.ElementTree as ET 


if __name__ == "__main__": 

tree = ET.parse('total-test.xml') 
root = tree.getroot() 

# remove <carFollowing> subelement from each vType 
vTypes = root.findall("vType") 
for vType in vTypes: 
    carFollowings = vType.findall("carFollowing-Krauss") 
    for carFollowing in carFollowings: 
     vType.remove(carFollowing) 

# remove each <vType> (to remove an element reference to its parent is required) 
for element in root: 
    if element.tag == "vType": 
     root.remove(element) 

# from root get into <vehicle> 
vehicles = root.findall("vehicle") 
for vehicle in vehicles: 
    # for each <vehicle> get reference <routeDistribution>s 
    routeDistributions = vehicle.findall("routeDistribution") 
    for routeDist in routeDistributions: 
     # for each vehicle distrbution get reference to <route>s 
     routes = routeDist.findall("route") 

     # fill a container with dictionaries which represent <route> attributes 
     listOfRouteDicts = list() 
     for route in routes: 
      listOfRouteDicts.append(route.attrib) 

     # find the min_cost for the given routes 
     min_cost = min(float(routeDict['cost']) for routeDict in listOfRouteDicts) 
     print(min_cost) 

     for route in routes: 
      if route.get('cost') == str(min_cost): 
       # remove the other attributes of the <route>, we only want the <edges> 
       route.attrib = {routeAttr:v for routeAttr,v in route.attrib.items() if routeAttr == "edges"} 
       vehicle.append(route) # move route one level-up to <vehicle> because <routeDistribution> needs to be removed 
      else: 
       routeDist.remove(route) # remove all routes which don't have the lowest cost 

    # remove the <routeDistribution> for each <vehicle> 
    vehicle.remove(routeDist) 
    vehicle.set('type', 'vTypeDist') 


tree.write('output.xml') 
+0

你可以有alook這裏:https://wiki.python.org/moin/MiniDom – Stefano

+0

@Stefano我還沒有嘗試過很多,只要我不熟悉Python中與xml相關的東西。因此,即使我認爲你已經做了一些更多的努力,然後只是要求爲你做腳本,我已經在下面發佈了一個「快速和骯髒」的代碼來幫助你入門,所以請打開我的建議 –

+0

。 – Stefano

回答

1

可能你需要一些更通用的東西。 下面的腳本將輸入(in.xml)並生成新的輸出(out.xml)。 肯定這不是很好的編碼,但它可以讓你開始使用語法,並幫助你將其推廣到你的需要。

from xml.dom.minidom import parse, parseString 

dom = parse("in.xml") # parse an XML file 
docRoot = dom.documentElement 

# delete all vType 
vTypeNode = docRoot.getElementsByTagName('vType')[0] 
docRoot.removeChild(vTypeNode) 

#i keep only first route node... second is the same... 
#but i am not sure if this will always be the case 
routeNode = docRoot.getElementsByTagName('route')[0] 

#remove all old route nodes 
vehicleNode = docRoot.getElementsByTagName('vehicle')[0] 
for child in vehicleNode.childNodes: 
    if child.nodeType == child.ELEMENT_NODE: 
     vehicleNode.removeChild(child) 

#create a new route node 
newRouteNode = dom.createElement("route") 
newRouteNode.setAttribute("edges" , routeNode.getAttribute("edges")) 

#append new node 
vehicleNode.appendChild(newRouteNode) 

#print output 
#print dom.toprettyxml() 

#write to file 
outFile = open("out.xml","wb") 
dom.writexml(outFile) 
outFile.close() 

N.B: 這僅僅是一個快速和骯髒,讓你開始!

編輯:

minidom命名ouptus總是很髒,因爲它包含了許多無用的空格。這是一個衆所周知的問題,但可以通過不同的方式輕鬆解決。您可能會感興趣有alook這裏:

problem with the new lines when I use toprettyxml()