无论我是构建树还是解析文件,lxml find 方法的运行方式都不同
lxml find method operates differently whether I'm building a tree or parsing a file
我正在编写一些 Python 代码,有时会从头开始构建 xml 树,有时会解析现有的 xml 并更新或报告它。我遇到的问题是 lxml find 和 findall 方法的操作似乎不同,这取决于我是在内存中构建树,还是从文件中解析它。命名空间似乎是问题所在。名称空间在根元素处定义(无前缀)。当我在内存中构造的树中的元素上使用查找时,将名称空间关键字与根 nsmap 添加会导致搜索不返回任何内容,但是当省略它时 returns 预期结果。但是,当从文件解析树时,情况恰恰相反。
编辑:我想我在这里缺少的是我需要明确地向 child 元素添加命名空间。
代码在这里分享有点冗长,但我已经在下面的一个粗略的片段中复制了这个问题。
from lxml import etree
import os
fname = 'test.xml'
if os.path.exists(fname):
root = etree.parse(fname).getroot()
try:
print('no namespaces -', root.find('title').text) #this doesn't work
except AttributeError as e:
print(e)
try:
print('namespaced -', root.find('title', namespaces=root.nsmap).text) #this works
except AttributeError as e:
print(e)
else:
root = etree.Element(
'DC',
nsmap={None: "http://purl.org/dc/elements/1.1/"})
etree.SubElement(root, 'title').text = "A title"
try:
print('no namespaces -', root.find('title').text) #this works
except AttributeError as e:
print(e)
try:
print('namespaced -', root.find('title', namespaces=root.nsmap).text) #this doesn't work
except AttributeError as e:
print(e)
tree = etree.ElementTree(root)
tree.write(fname)
如果您 运行 上面的一次,它将找到标题元素并使用未命名空间的查找打印值。但是如果你再次 运行 它,它只会使用命名空间查找来查找标题元素。我在这里失踪了吗?
编辑:我想我缺少的是我需要在构建树时明确地将名称空间添加到 child 元素。
您需要在与 DC
.
相同的命名空间中创建 title
子元素
我平时用的是etree.QName()
.
尝试改变这个:
etree.SubElement(root, 'title').text = "A title"
对此:
etree.SubElement(root, etree.QName("{http://purl.org/dc/elements/1.1/}title")).text = "A title"
我正在编写一些 Python 代码,有时会从头开始构建 xml 树,有时会解析现有的 xml 并更新或报告它。我遇到的问题是 lxml find 和 findall 方法的操作似乎不同,这取决于我是在内存中构建树,还是从文件中解析它。命名空间似乎是问题所在。名称空间在根元素处定义(无前缀)。当我在内存中构造的树中的元素上使用查找时,将名称空间关键字与根 nsmap 添加会导致搜索不返回任何内容,但是当省略它时 returns 预期结果。但是,当从文件解析树时,情况恰恰相反。
编辑:我想我在这里缺少的是我需要明确地向 child 元素添加命名空间。 代码在这里分享有点冗长,但我已经在下面的一个粗略的片段中复制了这个问题。
from lxml import etree
import os
fname = 'test.xml'
if os.path.exists(fname):
root = etree.parse(fname).getroot()
try:
print('no namespaces -', root.find('title').text) #this doesn't work
except AttributeError as e:
print(e)
try:
print('namespaced -', root.find('title', namespaces=root.nsmap).text) #this works
except AttributeError as e:
print(e)
else:
root = etree.Element(
'DC',
nsmap={None: "http://purl.org/dc/elements/1.1/"})
etree.SubElement(root, 'title').text = "A title"
try:
print('no namespaces -', root.find('title').text) #this works
except AttributeError as e:
print(e)
try:
print('namespaced -', root.find('title', namespaces=root.nsmap).text) #this doesn't work
except AttributeError as e:
print(e)
tree = etree.ElementTree(root)
tree.write(fname)
如果您 运行 上面的一次,它将找到标题元素并使用未命名空间的查找打印值。但是如果你再次 运行 它,它只会使用命名空间查找来查找标题元素。我在这里失踪了吗?
编辑:我想我缺少的是我需要在构建树时明确地将名称空间添加到 child 元素。
您需要在与 DC
.
title
子元素
我平时用的是etree.QName()
.
尝试改变这个:
etree.SubElement(root, 'title').text = "A title"
对此:
etree.SubElement(root, etree.QName("{http://purl.org/dc/elements/1.1/}title")).text = "A title"