搜索文本并替换为lxml

时间:2015-07-27 12:59:31

标签: python xml lxml

我需要在多行XML文件中搜索文本,其中我有多个标记。 我的XML文件看起来像这样

<?xml version="1.0" encoding="utf-8"?>
<nc:data xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
    <system xmlns="http://www.abc.xyz">
      <context>
            <name>context_1</name>
            <host>
                <name>xyz</name>
                <tag1>
                    <name>pqr</name>
                    <role>s1</role>
                    <tag2>test</tag2>
                </tag1>
                <tag2>
                    <name>pqr</name>
                    <role>s1</role>
                    <tag2>test</tag2>
                </tag2>              
            </host>
      </context>
    </system>
</nc:data>

我想在XML文件中搜索文本"test"的外观,并在输出中列出其父标记。不幸的是我无法这样做。

我写的Python代码是:

import os
import xml 
import sys 
from xml.dom import minidom
import xml.etree.ElementTree as ET

def xml_parsing():
    ''' 
    with open('file.xml', 'rt') as f:
        tree = ET.parse(f)
        for node in tree.findall('.//context'):
            print node, node.tag, node.attrib
            url = node.attrib.get('tag1')
            print url 

xml_parsing()

我得到空白结果作为输出,无法做任何事情。我尝试了ElementTreelxml。我认为这与我试图使用findall找到的搜索模式有关。

请告知您的专家意见,现在应该尝试什么。

我也尝试了SAX方式,代码是这样的:

xmldoc = minidom.parse('file.xml')
reflist = xmldoc.getElementsByTagName('tag1')
print reflist[0].toxml()

但是,除了标签之间的值之外,这将返回完整的行。

1 个答案:

答案 0 :(得分:1)

查找元素的XPath表达式,无论XML文档中的元素名称和位置如何,文本值等于test都是//*[text()='test']//*[.='test']

考虑以下工作lxml示例,演示如何查找此类元素并更新值:

from lxml import etree as ET

xml = '''<?xml version="1.0" encoding="utf-8"?>
<nc:data xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
    <system xmlns="http://www.abc.xyz">
      <context>
            <name>context_1</name>
            <host>
                <name>xyz</name>
                <tag1>
                    <name>pqr</name>
                    <role>s1</role>
                    <tag2>test</tag2>
                </tag1>
                <tag2>
                    <name>pqr</name>
                    <role>s1</role>
                    <tag2>test</tag2>
                </tag2>              
            </host>
      </context>
    </system>
</nc:data>'''

tree = ET.fromstring(xml)
for node in tree.xpath("//*[.='test']"):
    #update node value with new text 'foo'
    node.text = 'foo'
    print ET.tostring(node)

输出

<tag2 xmlns="http://www.abc.xyz" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">foo</tag2>

<tag2 xmlns="http://www.abc.xyz" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">foo</tag2>