【问题标题】:Python XML Parsing with Tag Specific Info带有标签特定信息的 Python XML 解析
【发布时间】:2014-12-26 05:15:09
【问题描述】:

我有一个结构如下的 XML 文件:

<?xml version="1.0">
<title>
  <ch bk="Book1" num="1">
    <ver num="1">ver1 content</ver>
    <ver num="2">ver2 content</ver>
  </ch>
  <ch bk="Book1" num="2">
    <ver num="1">ver1 content</ver>
    <ver num="2">ver2 content</ver>
  </ch>
  <ch bk="Book2" num="1">
    <ver num="1">ver1 content</ver>
    <ver num="2">ver2 content</ver>
  </ch>
</title>

有没有办法可以在 python 中访问特定 ch num and book 的单个 ver 内容? (例如 access ver num=2 of ch num=2 of bk=Book1) 我已经查看了一些解析 XML 的 xml 模块类,但是它们通过 tagName 进行,我看不到在哪里可以输入诸如 num、bk 和 ch 之类的信息。 非常感谢!

【问题讨论】:

    标签: python xml parsing tree


    【解决方案1】:

    您可以使用精细的 表达式访问元素:

    XPath 解释

    // 代表相对递归搜索

    '//ch[@num="1"][@bk="Book1"]/ver[@num="1"]'
    #  ^      ^        ^           ^      ^
    # ch node |        |           |      |
    #  + attributes num = 1        |      |
    #  + AND Book attribute = 1    |      |
    #                           ver node  |
    #                           + num attribut = 1
    

    python 代码:

    from lxml import etree
    fp = open("/tmp/xml.xml")
    tree = etree.parse(fp)
    print(tree.xpath('//ch[@num="1"][@bk="Book1"]/ver[@num="1"]/text()')[0])
    

    【讨论】:

      【解决方案2】:

      使用 Python 标准库的xml.etree.ElementTree 的简单方法:

      import xml.etree.ElementTree as ET
      tree = ET.parse('yourfile.xml')
      
      def locate(chnum, bk, vernum):
          for ch in tree.findall('ch'):
              if ch.get('num') != chnum: continue
              if ch.get('bk') != bk: continue
              for ver in ch.findall('ver'):
                  if ver.get('num') != vernum: continue
                  return ver.text
          return None  # no such chapter/book/version combo found
      

      【讨论】:

        【解决方案3】:

        是的,你可以使用 xpath 来获取目标标签。

        >>> from lxml import etree
        >>> fp = open("test.html")
        >>> tree = etree.parse(fp)
        >>> r = tree.xpath('//ch[@num=2][@bk="Book1"]/ver/text()')
        >>> r
        ['ver1 content', 'ver2 content']
        

        【讨论】:

          【解决方案4】:

          这样,您可以将ver 作为元素访问。

          import xml.etree.ElementTree as etree
          
          tree = etree.ElementTree(file='input.xml')
          
          #inputs
          num = '1'
          bk = 'Book2'
          
          #list comprehension (assume num and bk is unique for ch)
          vers =  [ch.findall('ver') \
                   for ch in tree.findall('ch') \
                   if ch.attrib['num'] == num and ch.attrib['bk'] == bk][0]
          
          #loop results
          for ver in vers:
              print 'num={0} text={1}'.format(ver.attrib['num'], ver.text)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-07-01
            • 2018-10-31
            • 2012-07-22
            • 2013-11-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多