【问题标题】:lxml find tags by regexlxml 通过正则表达式查找标签
【发布时间】:2015-01-13 02:06:59
【问题描述】:

我正在尝试使用 lxml 来获取格式化为的标签数组

<TEXT1>TEXT</TEXT1>

<TEXT2>TEXT</TEXT2>

<TEXT3>TEXT</TEXT3>

我尝试过使用

xml_file.findall("TEXT*")

但这会搜索文字星号。

我也尝试过使用 ETXPath,但它似乎不起作用。 是否有任何 API 函数可以使用它,因为假设 TEXT 由整数附加并不是最漂亮的解决方案。

【问题讨论】:

    标签: python xml tags lxml


    【解决方案1】:

    是的,您可以使用regular expressions in lxml xpath

    这是一个例子:

    results = root.xpath(
        "//*[re:test(local-name(), '^TEXT.*')]",
        namespaces={'re': "http://exslt.org/regular-expressions"})
    

    当然,在您提到的示例中,您实际上并不需要正则表达式。你可以使用starts-with() xpath 函数:

    results = root.xpath("//*[starts-with(local-name(), 'TEXT')]")
    

    完整的程序:

    from lxml import etree
    
    root = etree.XML('''
        <root>
          <TEXT1>one</TEXT1>
          <TEXT2>two</TEXT2>
          <TEXT3>three</TEXT3>
          <x-TEXT4>but never four</x-TEXT4>
        </root>''')
    
    result1 = root.xpath(
        "//*[re:test(local-name(), '^TEXT.*')]",
        namespaces={'re': "http://exslt.org/regular-expressions"})
    
    result2 = root.xpath("//*[starts-with(local-name(), 'TEXT')]")
    
    assert(result1 == result2)
    
    for result in result1:
        print result.text, result.tag
    

    解决一个新的需求,考虑这个 XML:

    <root>
       <tag>
          <TEXT1>one</TEXT1>
          <TEXT2>two</TEXT2>
          <TEXT3>three</TEXT3>
       </tag>
       <other_tag>
          <TEXT1>do not want to found one</TEXT1>
          <TEXT2>do not want to found two</TEXT2>
          <TEXT3>do not want to found three</TEXT3>
       </other_tag>
    </root>
    

    如果想要查找所有TEXT 元素的直接子元素,它们是&lt;tag&gt; 元素:

    result = root.xpath("//tag/*[starts-with(local-name(), 'TEXT')]")
    assert(' '.join(e.text for e in result) == 'one two three')
    

    或者,如果想要所有 TEXT 元素,它们只是第一个 tag 元素的直接子元素:

    result = root.xpath("//tag[1]/*[starts-with(local-name(), 'TEXT')]")
    assert(' '.join(e.text for e in result) == 'one two three')
    

    或者,如果只想找到每个 tag 元素的第一个 TEXT 元素:

    result = root.xpath("//tag/*[starts-with(local-name(), 'TEXT')][1]")
    assert(' '.join(e.text for e in result) == 'one')
    

    资源:

    【讨论】:

    【解决方案2】:

    这里有一个想法:

    import lxml.etree
    
    doc = lxml.etree.parse('test.xml')
    elements = [x for x in doc.xpath('//*') if x.tag.startswith('TEXT')]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 2012-08-13
      • 2015-01-10
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      • 2017-08-21
      相关资源
      最近更新 更多