使用lxml,如何找到父节点的兄弟节点?

Sty*_*ize 2 python xml xpath lxml

XML不断抛弃曲线球.我很难找到一本我能理解的手册.所以我为过去几天的所有问题道歉.

无论如何,我有以下XML:

      <clade>
        <clade>
          <branch_length>0.5</branch_length>
          <clade>
            <name>MnPV1</name>
            <annotation>
<desc>Iotapapillomavirus 1</desc></annotation><chart><group>Iota</group></chart><branch_length>1.0</branch_length>
          </clade>
          <clade> 
Run Code Online (Sandbox Code Playgroud)

我想将此更改为:

  <clade>
    <clade>
      <branch_length>0.5</branch_length>
      <clade>
        <name bgstyle="green">MnPV1</name>
        <annotation><desc>Iotapapillomavirus 1</desc><uri>http://pave.niaid.nih.gov/#fetch?id=MnPV1REF&amp;format=Locus%20view&amp;hasStructure=none</uri></annotation><chart><group>Iota</group></chart><branch_length>1.0</branch_length>
      </clade>
      <clade>
Run Code Online (Sandbox Code Playgroud)

所以我想改变:

<name>MnPV1</name>
Run Code Online (Sandbox Code Playgroud)

至:

<name bgstyle="green">MnPV1</name>
Run Code Online (Sandbox Code Playgroud)

问题是,我正在寻找是否:

tree.xpath('//phylo:group[text()="Iota"]
Run Code Online (Sandbox Code Playgroud)

如果它是我想得到"组"节点的"叔叔",所以我可以编辑"名称"节点

这是我到目前为止提出的:

tree = lxml.etree.XML(data)
nsmap = {'phylo': 'http://www.phyloxml.org'}
matches = tree.xpath('//phylo:group[text()="Iota"]', namespaces=nsmap)
Run Code Online (Sandbox Code Playgroud)
for e in matches:
    uncle=e.getparent().getsibling() #however, getsibling() does not exist...
Run Code Online (Sandbox Code Playgroud)

我将不胜感激任何帮助(和/或lxml for dummies的建议).

D.S*_*ley 5

这个怎么样?

>>> data = r'''<clade>
...  <name>MnPV1</name>
...  <annotation>
...    <desc>Iotapapillomavirus 1</desc>
...  </annotation>
...  <chart>
...    <group>Iota</group>
...  </chart>
...  <branch_length>1.0</branch_length>
... </clade>'''
...
>>> tree = lxml.etree.XML(data)
>>> for name in tree.xpath('//group[text()="Iota"]/../preceding-sibling::name'):
...   name.attrib['bgstyle'] = 'green'
...
>>> print lxml.etree.tostring(tree, pretty_print=True)
<clade>
 <name bgstyle="green">MnPV1</name>
 <annotation>
   <desc>Iotapapillomavirus 1</desc>
 </annotation>
 <chart>
   <group>Iota</group>
 </chart>
 <branch_length>1.0</branch_length>
</clade>

>>>
Run Code Online (Sandbox Code Playgroud)

诀窍是使用XML工具(例如,XPath和XSLT)来操作XML文档.在W3Schools的网站是相当不错的出发点.XPath本身就相当强大,一旦掌握了它就很容易阅读.但是,使用XSLT可以最好地解决此类问题.如果您要操作一堆XML,请自己做一件大事,购买一份Oxygen XML编辑器或类似的东西.

如果您正在寻找使用较少XPath和更多Python的东西,那么请使用getparent后跟调用getprevious.我不知道如何很好的支持getparentgetprevious,但它们都记录和做的工作.