Python 使用lxml,如何找到父节点的同级节点?

Python 使用lxml,如何找到父节点的同级节点?,python,xml,xpath,lxml,Python,Xml,Xpath,Lxml,XML不断地向我抛出曲线球。我很难找到一本我能理解的手册。所以,我为过去几天的所有问题道歉 在任何情况下,我都有以下XML: <clade> <clade> <branch_length>0.5</branch_length> <clade> <name>MnPV1</name> <annot

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> 
如果是,我想得到“组”节点的“叔叔”,这样我就可以编辑“名称”节点

这就是我到目前为止的想法:

tree=lxml.etree.XML(数据)
nsmap={'phylo':'http://www.phyloxml.org'}
matches=tree.xpath('//phylo:group[text()=“Iota”]”,名称空间=nsmap)
对于匹配中的e:
uncle=e.getparent().getsibling()#但是,getsibling()不存在。。。
如果您能提供任何帮助(和/或为假人提供lxml建议),我将不胜感激。

这个怎么样

>>> 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>

>>>
>data=r''
...  MnPV1
...   这些都是很好的起点。XPath本身就相当强大,一旦掌握了诀窍,就相当可读。不过,最好使用XSLT来解决这类问题。如果您要处理一堆XML,请帮自己一个大忙,购买一份或类似的东西


如果您希望使用更少的XPath和更多的Python,那么请使用以下命令,然后再调用。我不确定
getparent
getprevious
的支持程度如何,但它们是有文档记录的,并且确实有效

这里有一个简单的XSLT解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="clade[chart/group='Iota']/name">
  <name bgstyle="green"><xsl:apply-templates/></name>
 </xsl:template>
</xsl:stylesheet>
<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>
</clade>

在提供的XML文档上应用此转换时:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="clade[chart/group='Iota']/name">
  <name bgstyle="green"><xsl:apply-templates/></name>
 </xsl:template>
</xsl:stylesheet>
<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>
</clade>

0.5
MnPV1
,它“按原样”复制每个节点(为其选择要执行的节点)

  • 简单重写模板,匹配所需的
    名称
    元素,并将其替换为具有所需新属性的同名元素


  • 有一种
    getnext()
    方法,我认为这就是你所说的
    getsibling()
    @style的意思,如果你打算大量使用XML文档,我强烈建议你学习XSLT。我很少使用其他任何东西来操作XML文档。对于用于选择的更干净的XPath,加上1。
    <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>
    </clade>
    
    <clade>
       <clade>
          <branch_length>0.5</branch_length>
          <clade>
             <name bgstyle="green">MnPV1</name>
             <annotation>
                <desc>Iotapapillomavirus 1</desc>
             </annotation>
             <chart>
                <group>Iota</group>
             </chart>
             <branch_length>1.0</branch_length>
          </clade>
       </clade>
    </clade>