2016-04-22 78 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()