Radheya
Radheya

Reputation: 821

writing edited xml content to another file issue - python

I have two xml files as given below and I want to check the order of file B with file A (File B should follow File A's order). I also have written a program below which does the job of maintaining the order, the only problem is I am not able to correctly write the output to the another xml file. Before asking here I did researched about how to write edited xml files back to source or another file but maybe I am missing something very minor.

File A

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<p1:sample1 xmlns:p1="http://www.example.org/eHorizon">
<p1:time nTimestamp="1">
   <p1:location hours = "1" path = '1'>       
      <p1:feature color="6" type="a">560</p1:feature>
   </p1:location>
</p1:time>
<p1:time nTimestamp="2">
   <p1:location hours = "1" path = '1'>
      <p1:feature color="2" type="a">564</p1:feature>         
   </p1:location>
</p1:time>
<p1:time nTimestamp="3">
   <p1:location hours = "1" path = '1'>       
      <p1:feature color="6" type="a">560</p1:feature>          
   </p1:location>
</p1:time>
</p1:sample1>

File B

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<p1:sample1 xmlns:p1="http://www.example.org/eHorizon">
<p1:time nTimestamp="1">
   <p1:location hours = "1" path = '1'>       
      <p1:feature color="6" type="a">560</p1:feature>     
   </p1:location>
</p1:time>
<p1:time nTimestamp="3">
   <p1:location hours = "1" path = '1'>
      <p1:feature color="6" type="a">560</p1:feature>     
   </p1:location>
</p1:time>
<p1:time nTimestamp="2">
   <p1:location hours = "1" path = '1'>       
      <p1:feature color="2" type="a">564</p1:feature>      
   </p1:location>
</p1:time>
</p1:sample1>

Just for your information the only difference here is the order of entire p1:time element which are denoted by nTimestamps and its sub elements like location and feature. You can see that in File A it is 1,2,3... and in File B it is 1,3,2... (I am talking about entire p1:time element and everything inside)

What I want

from lxml import etree
from collections import defaultdict
from distutils.filelist import findall
from lxml._elementpath import findtext



recovering_parser = etree.XMLParser(recover=True)

Reference = etree.parse("C:/Users/your_location/Desktop/sample1.xml", parser=recovering_parser)
Copy = etree.parse("C:/Users/your_location/Desktop/sample2.xml", parser=recovering_parser)


ReferenceTest = Reference.findall("{http://www.example.org/eHorizon}time") #find all time elements in sample1
CopyTest = Copy.findall("{http://www.example.org/eHorizon}time") #find all time elements in sample2

a=[] #list for storing sample1's Time elements
b=[] #list for storing sample2's Time elements
new_list=[] #for storing sorted data

for i,j in zip(ReferenceTest,CopyTest):

    a.append((i, i.attrib.get("nTimestamp"))) # store data in format [(<Element {http://www.example.org/eHorizon}time at 0x213d738>, '1')  
                                              # where 1,2 or 3 is ntimestamp attribute and corresponding parent 'time' element of that attribute
    b.append((j, j.attrib.get("nTimestamp"))) # same as above 

def sortTimestamps(a,b):   #use this function to sort elements in 'b' list in such a manner that they follow sequence of 'a' list 

    for i in a:
        for j in b:
            if i[1]==j[1]:
                s = a.index(i)
                t = b.index(j)
                b[t],b[s]=b[s],b[t]     



sortTimestamps(a, b)  # call sort function 

for i in b:
    new_list.append(i[0]) # store the sorted timestamps in new_list


CopyTest = new_list # assign new sorted list of time elements to old list

Copy.write("C:/Users/your_location/Desktop/output_data.xml") # write data to another file and check results 

Above is the code that does the work for sorting B File according to order of File A. But when I write the program to another file, it writes File B's data as it is. That is to say it writes data in the same manner as it is shown in File B above. After sorting I expect that File B's data order should be modified and it should write data in format as given in File A

What I tried

Apart from program above I tried reading more on file writing but its getting me to nowhere. I checked format of my xml which i believe is totally fine. Finally i also followed a tutorial here just to see how it shows writing, but that approach is not working either. Maybe you guys can help me out.

Edit: I removed code from link and added it here. I did it previously to prevent long post

Upvotes: 0

Views: 98

Answers (1)

Anand S Kumar
Anand S Kumar

Reputation: 90909

This would not work , you are just assigning a new list to the old list - CopyTest . That does not change anything within the actual xml.

The easiest way for you to go would be to create the xml again from the elements in the new_list. Example -

root = etree.Element('{http://www.example.org/eHorizon}sample1',nsmap={'p1':'http://www.example.org/eHorizon'})
for elem in new_list:
    root.append(elem)

etree.ElementTree(root).write("c.xml") # write data to another file and check results 

You should replace the above lines, inplace of the CopyTest = new_list and the line after that.

Upvotes: 1

Related Questions