控制搜索深度 findall Lxml
Control search depth findall Lxml
我是 Python 的初学者,正在尝试使用 python 中的 LXML 解析 XML。我正在尝试使用 finall() 搜索标签,但希望控制深度,我可以在其中搜索标签,但搜索不会超出一个级别。解释如下:
<?xml version='1.0' encoding='utf-8'?>
<system xmlns="some_name_space">
<a>
<host>Random Name</host>
<class>
<name>Main_Tag_1</name>
<detail>
<name>Child_Tag_1</name>
<ip>ip_1</ip>
<port>port_1</port>
<detail>
</class>
<class>
<name>Main_Tag_2</name>
<detail>
<name>Child_Tag_2</name>
<ip>ip_2</ip>
<port>port_2</port>
<detail>
</class>
<class>
<name>Main_Tag_3</name>
<detail>
<name>Child_Tag_3</name>
<ip>ip_3</ip>
<port>port_3</port>
<detail>
</class>
</a>
我正在使用以下 python 来查找与 所有 Main_tags 共享相同标签名称的 name .我没有在这里添加完整的程序。但是这个函数是class的一部分。
def name_ip_dict(self,filename):
self.tag_replace = {}
context = ET.iterparse(filename, tag='{some_name_space}class')
for action,elem in context:
name_tag = elem.findall(".//{some_name_space}name")
for name in name_tag:
print name.text
for node in elem:
ip_list = node.findall(".//{some_name_space}ip")
for ip in ip_node_list:
self.tag_replace.setdefault(name.text, []).append(ip.text)
现在,我得到的输出是
{'Main_Tag_1': ['ip_1'], 'Child_tag_1': ['ip_1'], 'Main_Tag_2': ['ip_2'], 'Child_tag_1': ['ip_2']} and so on..
但我只想获取第一个父级,即 Main_Tag1、2 或 3 以及 ip 标签中的文本。
{'Main_Tag_1': ['ip_1'], 'Main_Tag_2': ['ip_2']} and so on..
这让我觉得有必要控制findall的深度,但我一直没能在网上找到任何与深度相关的东西。
如果已经有这样的用例,请告诉我,实现这个的最佳方法是什么。
如果只想在直接子元素(不包括孙子元素和更深的后代元素)中搜索,请使用单斜杠 (/
):
name_tag = elem.findall("./{some_name_space}name")
请注意,当您需要支持更高级的 XPath 表达式时,请使用 lxml
的 xpath()
method instead of findall()
. The latter only support a very limited set XPath 表达式。
我是 Python 的初学者,正在尝试使用 python 中的 LXML 解析 XML。我正在尝试使用 finall() 搜索标签,但希望控制深度,我可以在其中搜索标签,但搜索不会超出一个级别。解释如下:
<?xml version='1.0' encoding='utf-8'?>
<system xmlns="some_name_space">
<a>
<host>Random Name</host>
<class>
<name>Main_Tag_1</name>
<detail>
<name>Child_Tag_1</name>
<ip>ip_1</ip>
<port>port_1</port>
<detail>
</class>
<class>
<name>Main_Tag_2</name>
<detail>
<name>Child_Tag_2</name>
<ip>ip_2</ip>
<port>port_2</port>
<detail>
</class>
<class>
<name>Main_Tag_3</name>
<detail>
<name>Child_Tag_3</name>
<ip>ip_3</ip>
<port>port_3</port>
<detail>
</class>
</a>
我正在使用以下 python 来查找与 所有 Main_tags 共享相同标签名称的 name .我没有在这里添加完整的程序。但是这个函数是class的一部分。
def name_ip_dict(self,filename):
self.tag_replace = {}
context = ET.iterparse(filename, tag='{some_name_space}class')
for action,elem in context:
name_tag = elem.findall(".//{some_name_space}name")
for name in name_tag:
print name.text
for node in elem:
ip_list = node.findall(".//{some_name_space}ip")
for ip in ip_node_list:
self.tag_replace.setdefault(name.text, []).append(ip.text)
现在,我得到的输出是
{'Main_Tag_1': ['ip_1'], 'Child_tag_1': ['ip_1'], 'Main_Tag_2': ['ip_2'], 'Child_tag_1': ['ip_2']} and so on..
但我只想获取第一个父级,即 Main_Tag1、2 或 3 以及 ip 标签中的文本。
{'Main_Tag_1': ['ip_1'], 'Main_Tag_2': ['ip_2']} and so on..
这让我觉得有必要控制findall的深度,但我一直没能在网上找到任何与深度相关的东西。
如果已经有这样的用例,请告诉我,实现这个的最佳方法是什么。
如果只想在直接子元素(不包括孙子元素和更深的后代元素)中搜索,请使用单斜杠 (/
):
name_tag = elem.findall("./{some_name_space}name")
请注意,当您需要支持更高级的 XPath 表达式时,请使用 lxml
的 xpath()
method instead of findall()
. The latter only support a very limited set XPath 表达式。