用lxml装饰xml子树

时间:2013-10-29 22:10:36

标签: python xml lxml

我想转换这个xml树

<doc>
  <a>
    <op>xxx</op>
  </a>
</doc>

<doc>
  <a>
    <cls>
      <op>xxx</op>
    </cls>
  </a>
</doc>

我使用这个python代码

from lxml import etree
f = etree.fromstring('<doc><a><op>xxx</op></a></doc>')

node_a = f.xpath('/doc/a')[0]
ele = etree.Element('cls')
node_a.insert(0, ele)

node_cls = f.xpath('/doc/a/cls')[0]
node_op = f.xpath('/doc/a/op')[0] 
node_cls.append(node_op) 
print etree.tostring(f, pretty_print=True)

这是最好的解决方案吗?

现在我想获得

<cls>
  <doc>
    <a>
      <op>xxx</op>    
    </a>
  </doc>
</cls>

我无法找到任何解决方案。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我更喜欢更好。我发现它更容易处理。

使用相同的方法可以解决这两个问题,首先找到元素,获取其父元素,创建新元素并将旧元素放入其中。

from bs4 import BeautifulSoup
import sys 

soup = BeautifulSoup(open(sys.argv[1], 'r'), 'xml')
for e in soup.find_all(sys.argv[2]):
    p = e.parent
    cls = soup.new_tag('cls')
    e_extracted = e.extract()
    cls.append(e_extracted)
    p.append(cls)

print(soup.prettify())

脚本接受两个参数,第一个是xml文件,第二个是用新标签包围的标签。像以下一样运行:

python3 script.py xmlfile op

产量:

<?xml version="1.0" encoding="utf-8"?>
<doc>
 <a>
  <cls>
   <op>
    xxx
   </op>
  </cls>
 </a>
</doc>

对于<doc>,请按以下方式运行:

python3 script.py xmlfile doc

以下结果:

<?xml version="1.0" encoding="utf-8"?>
<cls>
 <doc>
  <a>
   <op>
    xxx
   </op>
  </a>
 </doc>
</cls>