【问题标题】:Python lxml: how to fetch XML tag names with xpath selector?Python lxml:如何使用 xpath 选择器获取 XML 标记名称?
【发布时间】:2019-09-06 16:13:16
【问题描述】:

我正在尝试使用 Python 和 lxml 解析以下 XML:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/bind9.xsl"?>
<isc version="1.0">
  <bind>
    <statistics version="2.2">
      <memory>
        <summary>
          <TotalUse>1232952256
          </TotalUse>
          <InUse>835252452
          </InUse>
          <BlockSize>598212608
          </BlockSize>
          <ContextSize>52670016
          </ContextSize>
          <Lost>0
          </Lost>
        </summary>
      </memory>
    </statistics>
  </bind>
</isc>

目标是提取bind/statistics/memory/summary 下每个元素的标签名称和文本,以生成以下映射:

TotalUse: 1232952256
InUse: 835252452
BlockSize: 598212608
ContextSize: 52670016
Lost: 0

我已经设法提取了元素值,但我无法找出 xpath 表达式来获取元素标签名称。

一个示例脚本:

from lxml import etree as et

def main():

    xmlfile = "bind982.xml"
    location = "bind/statistics/memory/summary/*"
    label_selector = "??????" ## what to put here...?
    value_selector = "text()"

    with open(xmlfile, "r") as data:
        xmldata = et.parse(data)

        etree = xmldata.getroot()

        statlist = etree.xpath(location)

        for stat in statlist:
            label = stat.xpath(label_selector)[0]
            value = stat.xpath(value_selector)[0]
            print "{0}: {1}".format(label, value)

if __name__ == '__main__':
    main()

我知道我可以使用value = stat.tag 而不是stat.xpath(),但脚本必须足够通用,才能处理标签选择器不同的其他 XML 片段。

什么 xpath 选择器会返回元素的标签名称?

【问题讨论】:

    标签: python xml xpath lxml


    【解决方案1】:

    只需使用 XPath 的 name(),并删除零索引,因为这会返回字符串而不是列表。

    from lxml import etree as et
    
    def main():
    
        xmlfile = "ExtractXPathTagName.xml"
        location = "bind/statistics/memory/summary/*"
        label_selector = "name()"                         ## what to put here...?
        value_selector = "text()"
    
        with open(xmlfile, "r") as data:
            xmldata = et.parse(data)
    
            etree = xmldata.getroot()
    
            statlist = etree.xpath(location)
    
            for stat in statlist:
                label = stat.xpath(label_selector)
                value = stat.xpath(value_selector)[0]
                print("{0}: {1}".format(label, value).strip())
    
    if __name__ == '__main__':
        main()
    

    输出

    TotalUse: 1232952256    
    InUse: 835252452    
    BlockSize: 598212608    
    ContextSize: 52670016    
    Lost: 0
    

    【讨论】:

      【解决方案2】:

      我认为这两个值不需要 XPath,元素节点具有属性 tagtext 所以例如使用列表理解:

      [(element.tag, element.text) for element in etree.xpath(location)]
      

      或者如果你真的想使用 XPath

      result = [(element.xpath('name()'), element.xpath('string()')) for element in etree.xpath(location)]
      

      您当然也可以构建一个字典列表:

      result = [{ element.tag : element.text } for element in root.xpath(location)]
      

      result = [{ element.xpath('name()') : element.xpath('string()') } for element in etree.xpath(location)]
      

      【讨论】:

        猜你喜欢
        • 2022-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-09
        • 1970-01-01
        • 2014-03-01
        相关资源
        最近更新 更多