Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用python脚本修改xml文件_Python_Xml - Fatal编程技术网

用python脚本修改xml文件

用python脚本修改xml文件,python,xml,Python,Xml,如何修改以下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

如何修改以下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>

也许你需要一些更通用的东西。 下面的脚本接受您的输入(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总是非常脏,因为它包含许多无用的空格。这是一个众所周知的问题,但可以通过不同的方式轻松解决。您可能有兴趣在此处查看:


你可以在这里看看:@Stefano我还没有尝试过很多,因为我不熟悉Python中与xml相关的东西。所以,欢迎你的建议,即使我认为你应该在简单地邀请别人为你做脚本之前多做点努力,我在下面发布了一个“快速而肮脏”的代码,让你开始。我同意你的看法。。。开始玩ElementTree。。。你有什么理由选择minidom而不是它吗?不是真的。。。dom/minidom只是更经典的库。我还曾经使用lxml2,它非常快。LXML是另一个。我认为这是基于libxml2的,但应该提供更好的接口。
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')
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()