使用Python在ElementTree

时间:2017-10-15 23:01:19

标签: python xml

使用Python 3.6我在xml.etree.ElementTree中有如下所示的数据,使用minidom.toprettyxml的xml输出如下所示。

在输出到XML文件之前,我想使用PT属性作为键对Observation节点进行排序。同时将它们保存在正确的Setup节点中。

这是出于人类阅读目的,因此对同一“PT”的“观察”彼此相邻以进行检查,并且可能手动编辑。

提前感谢您的帮助。

<?xml version="1.0" ?>
<Survey name="filename here">
<Setup Station="13000" InstrumentHeight="0.0">
<Observation PT="SBDSE852S" HA="336.4813486486353" VA="87.14710969026532" SD="168.8937" TH="0.0" Face="F1" Time="2016-05-21T15:47:39.03"/>
<Observation PT="SBTW801S" HA="260.9403472908128" VA="88.11265463299148" SD="224.61925" TH="0.0" Face="F1" Time="2016-05-21T15:49:05.02"/>
<Observation PT="SBTW802S" HA="249.90718352859065" VA="88.20019946435063" SD="221.16645" TH="0.0" Face="F1" Time="2016-05-21T15:49:56.05"/>
<Observation PT="SBZZ108R" HA="213.70079790293013" VA="87.84023471948807" SD="129.7161" TH="0.0" Face="F1" Time="2016-05-21T15:52:17.04"/>
<Observation PT="SBGC210R" HA="131.9100549303175" VA="86.83200793760854" SD="31.1457" TH="0.0" Face="F1" Time="2016-05-21T15:56:24.08"/>
<Observation PT="SBGC201R" HA="135.24920297621932" VA="87.42093979205845" SD="35.22585" TH="0.0" Face="F1" Time="2016-05-21T15:57:19.08"/>
<Observation PT="SBGC300R" HA="341.0439328237202" VA="94.9602466892515" SD="16.3769" TH="0.0" Face="F1" Time="2016-05-21T15:58:31.03"/>
<Observation PT="SBGC300R" HA="341.04415608692466" VA="94.96029050152956" SD="16.37675" TH="0.0" Face="F1" Time="2016-05-21T15:59:36.06"/>
<Observation PT="SBGC301R" HA="38.42640483483226" VA="62.94180376378161" SD="7.64965" TH="0.0" Face="F1" Time="2016-05-21T16:00:30.00"/>
</Setup>
<Setup Station="13001" InstrumentHeight="0.0">
<Observation PT="SBMOSI105S" HA="219.1574438207224" VA="86.35383331578822" SD="114.80255" TH="0.0" Face="F1" Time="2016-05-21T16:23:19.02"/>
<Observation PT="SBGC300R" HA="325.74302017491317" VA="92.11049818613618" SD="47.7476" TH="0.0" Face="F1" Time="2016-05-21T16:24:41.09"/>
<Observation PT="SBGC211R" HA="28.812142606012266" VA="64.25698410412183" SD="3.09595" TH="0.0" Face="F1" Time="2016-05-21T16:25:27.03"/>
<Observation PT="SBGC201R" HA="106.99533526950749" VA="69.72099653614151" SD="3.5871" TH="0.0" Face="F1" Time="2016-05-21T16:26:33.00"/>
<Observation PT="SBGC205R" HA="218.37692405247293" VA="89.04822501002216" SD="54.39005" TH="0.0" Face="F1" Time="2016-05-21T16:29:09.08"/>
<Observation PT="SBTW801S" HA="267.32946750582306" VA="88.34255274658865" SD="243.62085" TH="0.0" Face="F1" Time="2016-05-21T16:31:52.06"/>
<Observation PT="SBTW802S" HA="314.721253630381" VA="88.54860755337845" SD="157.8072" TH="0.0" Face="F1" Time="2016-05-21T16:33:57.08"/>
</Setup>
<Setup Station="13002" InstrumentHeight="0.0">
<Observation PT="SBDSE852S" HA="354.56003832181915" VA="86.26412763401385" SD="106.19915" TH="0.0" Face="F1" Time="2016-05-21T16:50:14.05"/>
<Observation PT="SBTW802S" HA="230.23156694768846" VA="88.40135183495619" SD="195.66635" TH="0.0" Face="F1" Time="2016-05-21T16:51:15.06"/>
<Observation PT="SBTW803S" HA="226.3231844045" VA="88.39109127019015" SD="190.51305" TH="0.0" Face="F1" Time="2016-05-21T16:52:16.01"/>
<Observation PT="SBMOSI106S" HA="187.5030019464116" VA="87.90409405603675" SD="157.9494" TH="0.0" Face="F1" Time="2016-05-21T16:53:21.09"/>
<Observation PT="SBMOSI105S" HA="177.7109399309417" VA="87.82634136047567" SD="162.26865" TH="0.0" Face="F1" Time="2016-05-21T16:53:46.03"/>
<Observation PT="SBTW901L" HA="18.641385181822482" VA="88.81520162210843" SD="279.27325" TH="0.0" Face="F1" Time="2016-05-21T16:54:34.05"/>
<Observation PT="SBCS102R" HA="30.472020884007478" VA="88.96897044168112" SD="229.89725" TH="0.0" Face="F1" Time="2016-05-21T16:56:05.08"/>
<Observation PT="SBMAR101R" HA="115.15110363661125" VA="90.62341735945346" SD="111.59105" TH="0.0" Face="F1" Time="2016-05-21T16:57:01.04"/>
<Observation PT="SBWS503R" HA="170.9342211846535" VA="88.35831296215247" SD="164.259" TH="0.0" Face="F1" Time="2016-05-21T16:58:10.06"/>
<Observation PT="SBWS501" HA="170.94714304485467" VA="89.04669321908078" SD="164.0959" TH="0.0" Face="F1" Time="2016-05-21T16:58:59.03"/>
<Observation PT="SBTW301" HA="247.14604037600958" VA="87.51229331444699" SD="90.3724" TH="0.0" Face="F1" Time="2016-05-21T17:00:30.09"/>
<Observation PT="SBTW301" HA="247.14649473022342" VA="87.51186961100264" SD="90.37245" TH="0.0" Face="F1" Time="2016-05-21T17:00:48.06"/>
<Observation PT="SBTW400R" HA="285.3028326362871" VA="86.38080898316367" SD="49.01575" TH="0.0" Face="F1" Time="2016-05-21T17:03:07.01"/>
<Observation PT="SBTW401R" HA="290.8527087321224" VA="86.70593184736977" SD="47.866" TH="0.0" Face="F1" Time="2016-05-21T17:03:59.00"/>
<Observation PT="SBTW402R" HA="294.2822760524366" VA="86.25402786881274" SD="47.4713" TH="0.0" Face="F1" Time="2016-05-21T17:05:53.03"/>
<Observation PT="SBTW403R" HA="298.85861455642316" VA="86.05166064933604" SD="47.2702" TH="0.0" Face="F1" Time="2016-05-21T17:06:38.08"/>
<Observation PT="SBTW404R" HA="304.5271278231994" VA="86.5688961106161" SD="47.42415" TH="0.0" Face="F1" Time="2016-05-21T17:07:39.05"/>
<Observation PT="SBTW406R" HA="318.67206741643145" VA="86.75902245348605" SD="50.45355" TH="0.0" Face="F1" Time="2016-05-21T17:09:11.09"/>
<Observation PT="SBTW399R" HA="281.128645158443" VA="86.82591448775327" SD="50.2397" TH="0.0" Face="F1" Time="2016-05-21T17:10:24.03"/>
</Setup>
<Setup Station="temp" InstrumentHeight="1.884">
<Observation PT="PSAL2" HA="24.068185256074244" VA="90.31240301123276" SD="320.11305" TH="1.621" Face="F1" Time="2016-05-17T13:28:56.09"/>
<Observation PT="SBTW202N" HA="245.06715785883776" VA="91.30625622434441" SD="123.5903" TH="1.656" Face="F1" Time="2016-05-17T13:30:15.08"/>
<Observation PT="r500" HA="123.62013964872175" VA="87.95780370215967" SD="107.6492" TH="0.0" Face="F1" Time="2016-05-17T13:36:19.00"/>
<Observation PT="r500" HA="123.6203153322358" VA="87.95560522722639" SD="107.6492" TH="0.0" Face="F2" Time="2016-05-17T13:36:27.09"/>
<Observation PT="r501" HA="130.84384878983974" VA="87.60171192430147" SD="82.6911" TH="0.0" Face="F2" Time="2016-05-17T13:37:21.03"/>
<Observation PT="r501" HA="130.84344197077056" VA="87.60288510425652" SD="82.6914" TH="0.0" Face="F1" Time="2016-05-17T13:37:30.06"/>
<Observation PT="r502" HA="241.99108056014126" VA="87.19343867580737" SD="61.9447" TH="0.0" Face="F1" Time="2016-05-17T13:38:21.01"/>
<Observation PT="r502" HA="241.98884425774403" VA="87.19455666305743" SD="61.9449" TH="0.0" Face="F2" Time="2016-05-17T13:38:31.09"/>
<Observation PT="r600" HA="68.57120263560662" VA="92.3163684670261" SD="118.4461" TH="0.0" Face="F1" Time="2016-05-17T13:56:07.02"/>
<Observation PT="r500" HA="123.61993021166316" VA="87.9573717396231" SD="107.6494" TH="0.0" Face="F1" Time="2016-05-17T14:04:03.04"/>
<Observation PT="r501" HA="130.84345337552227" VA="87.60319149277143" SD="82.6914" TH="0.0" Face="F1" Time="2016-05-17T14:04:08.05"/>
<Observation PT="r502" HA="241.9909586725194" VA="87.19352688879648" SD="61.9443" TH="0.0" Face="F1" Time="2016-05-17T14:04:15.05"/>
<Observation PT="SBTW302" HA="0.9611840906508888" VA="88.97526186816492" SD="68.7253" TH="0.0" Face="F1" Time="2016-05-17T14:04:41.04"/>
<Observation PT="SBTW304" HA="11.876418609524151" VA="88.9228703279833" SD="93.1502" TH="0.0" Face="F1" Time="2016-05-17T14:04:46.06"/>
<Observation PT="SBTW305" HA="14.585281351673927" VA="89.00020199601738" SD="103.8175" TH="0.0" Face="F1" Time="2016-05-17T14:04:50.07"/>
<Observation PT="SBTW306" HA="16.628979034318128" VA="89.07322439029339" SD="115.2822" TH="0.0" Face="F1" Time="2016-05-17T14:04:55.05"/>
<Observation PT="SBTW307" HA="18.016836604589763" VA="89.12660432855284" SD="126.4392" TH="0.0" Face="F1" Time="2016-05-17T14:05:00.03"/>
<Observation PT="SBTW308" HA="18.97646817191739" VA="89.1495839098842" SD="137.5861" TH="0.0" Face="F1" Time="2016-05-17T14:05:04.09"/>
<Observation PT="SBTW801" HA="282.4367435665059" VA="87.52781194884842" SD="83.3535" TH="0.0" Face="F1" Time="2016-05-17T14:05:12.03"/>
<Observation PT="SBTW802" HA="251.37561061253402" VA="87.46269907513076" SD="71.0131" TH="0.0" Face="F1" Time="2016-05-17T14:05:18.04"/>
<Observation PT="SBTW901L" HA="24.06832955528608" VA="90.31347245253119" SD="320.1218" TH="0.0" Face="F1" Time="2016-05-17T14:05:40.08"/>
<Observation PT="SBTW901L" HA="24.06862223664632" VA="90.3122056771158" SD="320.1222" TH="0.0" Face="F2" Time="2016-05-17T14:06:16.02"/>
<Observation PT="SBTW802" HA="251.37472085862015" VA="87.4610177726289" SD="71.013" TH="0.0" Face="F2" Time="2016-05-17T14:06:24.05"/>
<Observation PT="SBTW801" HA="282.4352358258901" VA="87.52527499427424" SD="83.3537" TH="0.0" Face="F2" Time="2016-05-17T14:06:30.01"/>
<Observation PT="SBTW308" HA="18.975997216986002" VA="89.14645385139994" SD="137.5857" TH="0.0" Face="F2" Time="2016-05-17T14:06:37.09"/>
<Observation PT="SBTW307" HA="18.01649022896055" VA="89.12372242850097" SD="126.439" TH="0.0" Face="F2" Time="2016-05-17T14:06:42.02"/>
<Observation PT="SBTW306" HA="16.62829528228866" VA="89.06971709469389" SD="115.2822" TH="0.0" Face="F2" Time="2016-05-17T14:06:46.05"/>
<Observation PT="SBTW305" HA="14.58388062186225" VA="88.99686144292622" SD="103.8173" TH="0.0" Face="F2" Time="2016-05-17T14:06:51.00"/>
<Observation PT="SBTW304" HA="11.876229549713685" VA="88.92077538288771" SD="93.1499" TH="0.0" Face="F2" Time="2016-05-17T14:06:55.04"/>
<Observation PT="SBTW302" HA="0.9603442237767297" VA="88.97309321914179" SD="68.7252" TH="0.0" Face="F2" Time="2016-05-17T14:07:00.02"/>
<Observation PT="SBTW301" HA="359.92363229042274" VA="88.63199758491982" SD="67.4118" TH="0.0" Face="F2" Time="2016-05-17T14:07:04.09"/>
<Observation PT="r502" HA="241.99018294490645" VA="87.19196252085936" SD="61.9441" TH="0.0" Face="F2" Time="2016-05-17T14:07:26.05"/>
<Observation PT="r501" HA="130.84347383084798" VA="87.60109905138432" SD="82.6912" TH="0.0" Face="F2" Time="2016-05-17T14:07:34.07"/>
<Observation PT="r500" HA="123.61992158727509" VA="87.95497065120895" SD="107.6493" TH="0.0" Face="F2" Time="2016-05-17T14:07:39.09"/>
<Observation PT="r500" HA="123.62028513159477" VA="87.9572041239818" SD="107.6494" TH="0.0" Face="F1" Time="2016-05-17T14:07:49.08"/>
<Observation PT="r501" HA="130.84367916566217" VA="87.60325620929217" SD="82.6912" TH="0.0" Face="F1" Time="2016-05-17T14:07:54.06"/>
<Observation PT="r502" HA="241.9912233760674" VA="87.1935815782532" SD="61.9441" TH="0.0" Face="F1" Time="2016-05-17T14:08:02.07"/>
<Observation PT="SBTW301" HA="0.9584977661780416" VA="88.96683207497885" SD="68.7468" TH="0.0" Face="F1" Time="2016-05-17T14:08:26.01"/>
<Observation PT="SBTW302" HA="0.958732819126125" VA="88.96676159695137" SD="68.7257" TH="0.0" Face="F1" Time="2016-05-17T14:08:34.06"/>
<Observation PT="SBTW304" HA="11.876530899220256" VA="88.92270134487522" SD="93.1501" TH="0.0" Face="F1" Time="2016-05-17T14:08:39.05"/>
<Observation PT="SBTW305" HA="14.584397100867974" VA="88.99938939303587" SD="103.8174" TH="0.0" Face="F1" Time="2016-05-17T14:08:44.01"/>
<Observation PT="SBTW306" HA="16.628806129431375" VA="89.07242864357994" SD="115.2824" TH="0.0" Face="F1" Time="2016-05-17T14:08:48.05"/>
<Observation PT="SBTW307" HA="18.017194777740073" VA="89.12641910538291" SD="126.4391" TH="0.0" Face="F1" Time="2016-05-17T14:08:52.07"/>
<Observation PT="SBTW308" HA="18.975846749791895" VA="89.14930339919859" SD="137.5856" TH="0.0" Face="F1" Time="2016-05-17T14:08:56.06"/>
<Observation PT="SBTW801" HA="282.43714353985325" VA="87.52692851263892" SD="83.3535" TH="0.0" Face="F1" Time="2016-05-17T14:09:04.07"/>
<Observation PT="SBTW802" HA="251.37634286131873" VA="87.46239249096331" SD="71.0134" TH="0.0" Face="F1" Time="2016-05-17T14:09:10.08"/>
<Observation PT="SBTW901L" HA="24.06769842498717" VA="90.3134788970486" SD="320.1223" TH="0.0" Face="F1" Time="2016-05-17T14:09:24.08"/>
<Observation PT="SBTW901L" HA="24.067475499507026" VA="90.31237002761458" SD="320.122" TH="0.0" Face="F2" Time="2016-05-17T14:09:56.03"/>
<Observation PT="SBTW802" HA="251.37439019200136" VA="87.46064435777237" SD="71.0131" TH="0.0" Face="F2" Time="2016-05-17T14:10:05.04"/>
<Observation PT="SBTW801" HA="282.4351764980064" VA="87.52506030786941" SD="83.3538" TH="0.0" Face="F2" Time="2016-05-17T14:10:11.04"/>
<Observation PT="SBTW308" HA="18.975624352655785" VA="89.14663277740232" SD="137.5858" TH="0.0" Face="F2" Time="2016-05-17T14:10:19.01"/>
<Observation PT="SBTW307" HA="18.016732660526543" VA="89.12383098706346" SD="126.4389" TH="0.0" Face="F2" Time="2016-05-17T14:10:23.04"/>
<Observation PT="SBTW306" HA="16.6282233192303" VA="89.070045697122" SD="115.2823" TH="0.0" Face="F2" Time="2016-05-17T14:10:27.07"/>
<Observation PT="SBTW305" HA="14.58426043757268" VA="88.99693515968664" SD="103.8174" TH="0.0" Face="F2" Time="2016-05-17T14:10:32.03"/>
<Observation PT="SBTW304" HA="11.875751307745219" VA="88.92000621804061" SD="93.1501" TH="0.0" Face="F2" Time="2016-05-17T14:10:36.09"/>
<Observation PT="SBTW302" HA="0.9602230204149578" VA="88.97245731897425" SD="68.7253" TH="0.0" Face="F2" Time="2016-05-17T14:10:41.07"/>
<Observation PT="SBTW301" HA="359.9232477160593" VA="88.63150254883033" SD="67.4118" TH="0.0" Face="F2" Time="2016-05-17T14:10:47.08"/>
<Observation PT="r502" HA="241.9898596249429" VA="87.19233103560146" SD="61.9442" TH="0.0" Face="F2" Time="2016-05-17T14:11:07.04"/>
<Observation PT="r501" HA="130.8435622742349" VA="87.60103555448956" SD="82.691" TH="0.0" Face="F2" Time="2016-05-17T14:11:14.08"/>
<Observation PT="r500" HA="123.61956410801093" VA="87.95483969210812" SD="107.6492" TH="0.0" Face="F2" Time="2016-05-17T14:11:20.01"/>
</Setup>
</Survey>

下面我完整的Python代码,我无法对输出进行排序。

import untangle
import math

from xml.etree import ElementTree #modified ElementTree.py removing attribute sorting
from xml.etree.ElementTree import Element, SubElement, Comment, tostring
from xml.dom import minidom #modified minidom.py removing attribute sorting

def prettify(elem):
    """Return a pretty-printed XML string for the Element.
    """
    rough_string = ElementTree.tostring(elem, 'utf-8')
    reparsed = minidom.parseString(rough_string)
    return reparsed.toprettyxml(indent="")


## Start of Functions

def DMStoDD(DMSAng):
    DMSAng=str(DMSAng)
    p=DMSAng.find('.')
    D=DMSAng[0:p]
    M=DMSAng[p+1:p+3]
    S=DMSAng[p+3:p+5]
    SS='0.'+DMSAng[p+5:]
    DDAngStr=' '.join([D,' ',M,' ',S,' ',SS])
    DDAng= (
    float(D)
    +  float(M)/60
    +  float(S)/3600
    +  float(SS)/3600    
    )
    return DDAng



def DDtoDMS(DDAng2,Splaces=2):
    DDAng=float(DDAng2)
    D=int(DDAng)
    M=int((DDAng-D)*60)
    S=int((DDAng-D-M/60)*3600)
    SS=str(float((DDAng-D)-M/60-S/3600)*3600)[2:(2+Splaces)]

    DDtoDMS=(
        "%3.0f"%D + '.' +
        "%02.0f"%M +
        "%02.0f"%S +
        SS
        )

    return DDtoDMS

def DDtoDMSdash(DDAng2,Splaces=2):
    Splaces2 = Splaces
    if Splaces == 0:
        Splaces2 = -1
    DDAng=float(DDAng2)
    D=int(DDAng)
    M=int((DDAng-D)*60)
    S=float((DDAng-D-M/60)*3600)

    DDtoDMSdash=(
        "%3.0f"%D + '-' +
        "%02.0f"%M + '-' +
        ("%0"+str((Splaces2)+3)+"."+str(Splaces)+"f")%S
        )

    return DDtoDMSdash


##start of code
tree = untangle.parse('XML1.xml')
surv = tree.LandXML.Survey

## write ElementTree ROOT
Out = Element('Survey')
Out.set('name','filename here')

for OG in surv.ObservationGroup:
    ST=OG.TargetPoint['name']
    OGID=OG['id']
    ##find corresponding Instrument Height by cross-referencing to InstrumentSetup
    ISID=OGID[1:]    
    IH=0.000
    for IS in surv.InstrumentSetup:
        if IS['id'] == ISID:
            IH=float(IS['instrumentHeight'])

    ## Write ElementTree
    Set=SubElement(Out,'Setup')
    Set.set('Station',str(ST))
    Set.set('InstrumentHeight',str(IH))



    for RO in OG.RawObservation:
        HA=DMStoDD(str(RO['horizAngle']))
        VA=DMStoDD(str(RO['zenithAngle']))
        SD=float(RO['slopeDistance'])
        TH=float(RO['targetHeight'])
        if RO['directFace'] == 'true':
            F='F1'
        else:
            F='F2'
        PT=str(RO.TargetPoint['name'])
        T=str(RO['timeStamp'])
        ## Convert face 2 observations to face 1
        if F=='F2':
            HA=HA-180
            if HA < 0:
                HA = HA+360
            VA=360-VA
        ## Calc Vertical distance inclu0ding IH and TH
        ##VD=IH+SD*math.cos(math.radians(VA))-TH

        ##Write ElementTree
        Obs=SubElement(Set,'Observation',
                               {'PT':str(PT),
                                'HA':str(HA),
                                'VA':str(VA),
                                'SD':str(SD),
                                'TH':str(TH),
                                'Face':str(F),
                                'Time':str(T)
                                }
                               )

container = Out.find("Setup")

for a in container:
    data = []
    for elem in a:
        key = elem.findtext("PT")
        data.append((key,elem))
    data.sort()
    a[:] = [item[-1] for item in data]


print (prettify(Out))
#print (ElementTree.tostring(Out))







##        print (
##            ST,' ',
##            PT,' ',
##            "{:.4f}".format(HA),' ',
##            "{:.4f}".format(VA),' ',
##            "{:.3f}".format(SD),' ',
##            "{:.3f}".format(VD),' ',
##            "{:.3f}".format(IH),' ',
##            "{:.3f}".format(TH),' ',
##            F,' ',
##            T
##            )

1 个答案:

答案 0 :(得分:0)

这应该有效

def sortchildrenby(parent, attr):
    parent[:] = sorted(parent, key=lambda child: child.get(attr))

tree = ET.parse('data.xml')
parent = tree.find("Setup")
sortchildrenby(parent, "PT")
tree.write("new_data.xml")