<p>另一种方法,供您参考</p>
<pre><code>from simplified_scrapy import SimplifiedDoc, utils
xml = '''
<?xml version="1.0" ?>
<DefaultLines>
<Files Date="2020-10-23" Name="D:\report_byfile_detailed.txt">
<FileName file="emem_fifo_1c.vhd ">
<DefLines>
<Message>'120'<Child>Statement</Child>w_addr &lt;= (others =&gt; '0');</Message>
</DefLines>
<DefLines>
<Message>'136'<Child>Statement</Child>r_addr &lt;= (others =&gt; '0');</Message>
</DefLines>
</FileName>
<FileName file="some_other_name.text">
<DefLines>
<Message>'xxxx'<Child>Branch</Child>if (yyyyy= '1000') then</Message>
</DefLines>
</FileName>
<FileName file="emem_fifo_1c.vhd " id="mushi">
<DefLines>
<Message>'119'<Child>Branch</Child>if (SRESET = '1') then</Message>
</DefLines>
</FileName>
</Files>
</DefaultLines>
'''
dic = {}
doc = SimplifiedDoc(xml)
nodes = doc.selects('Files>FileName')
for node in nodes:
last = dic.get(node['file'])
if last:
last.appendChild(node.html)
node.remove()
else:
dic[node['file']]=node
# print (doc.html)
# remove the duplicate items
nodes = doc.selects('Files>FileName')
for node in nodes:
dic.clear()
lst = node.selects('DefLines')
if len(lst) <= 1:
continue
for n in lst:
key = n.select('Message').firstText()
exist = dic.get(key)
if exist:
n.remove()
else:
dic[key] = True
# Sort
nodes = doc.selects('Files>FileName')
for node in nodes:
dic.clear()
lst = node.selects('DefLines')
if len(lst) <= 1:
continue
for n in lst:
dic[n.select('Message').firstText()] = n.outerHtml # Cache, replace it below.
i = 0
for key in sorted(dic):
lst[i].replaceSelf(dic[key]) # Replace after sorting
i = i + 1
# Save
utils.saveFile('test.xml', doc.html)
</code></pre>
<p>结果:</p>
<pre><code><?xml version="1.0" ?>
<DefaultLines>
<Files Date="2020-10-23" Name="D: eport_byfile_detailed.txt">
<FileName file="emem_fifo_1c.vhd ">
<DefLines>
<Message>'119'<Child>Branch</Child>if (SRESET = '1') then</Message>
</DefLines>
<DefLines>
<Message>'120'<Child>Statement</Child>w_addr &lt;= (others =&gt; '0');</Message>
</DefLines>
<DefLines>
<Message>'136'<Child>Statement</Child>r_addr &lt;= (others =&gt; '0');</Message>
</DefLines>
</FileName>
<FileName file="some_other_name.text">
<DefLines>
<Message>'xxxx'<Child>Branch</Child>if (yyyyy= '1000') then</Message>
</DefLines>
</FileName>
</Files>
</DefaultLines>
</code></pre>