lxml通过正则表达式查找标签

jka*_*zka 4 python xml tags lxml

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

<TEXT1>TEXT</TEXT1>

<TEXT2>TEXT</TEXT2>

<TEXT3>TEXT</TEXT3>
Run Code Online (Sandbox Code Playgroud)

我试过用

xml_file.findall("TEXT*")
Run Code Online (Sandbox Code Playgroud)

但是这会搜索文字星号.

我也尝试使用ETXPath,但似乎无法正常工作.是否有任何API函数可以使用它,因为假设 TEXT是整数追加不是最漂亮的解决方案.

Rob*_*obᵩ 9

是的,您可以在lxml xpath中使用正则表达式.

这是一个例子:

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

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

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

完整计划:

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
Run Code Online (Sandbox Code Playgroud)

满足新要求,请考虑以下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>
Run Code Online (Sandbox Code Playgroud)

如果想要找到TEXT元素的直接子元素的所有元素<tag>:

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

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

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

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

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

Resorources: