在 lxml 中使用命名空间
Using namespaces in lxml
我正在尝试使用 lxml
进行 svg 解析并与命名空间作斗争。
问题:
- 如何使用
tree.iterfind
和名称空间映射遍历所有 image
标签? tree.iterfind('image', root.nsmap)
不重新调整任何东西,更丑陋的 tree.iter('{http://www.w3.org/2000/svg}image')
有效
- 我正在尝试将
image
标签转换为 use
标签。虽然 lxml 给了我一个带有 xlinx:href
的属性字典,但它在将它传递给 makeelement
时会窒息,有没有优雅的解决方案?
- 我应该使用
lxml
还是有更好的(更直接的)?我的目标是将 image
标签重写为 use
标签并将引用的 svgs 的内容嵌入到符号中。 (到目前为止 lxml
我对命名空间的问题似乎令人厌恶)。
.
from lxml import etree
def inlineSvg(path):
parser = etree.XMLParser(recover=True)
tree = etree.parse(path, parser)
root = tree.getroot()
print(root.nsmap)
for img in tree.iter('{http://www.w3.org/2000/svg}image'):
#for img in tree.iterfind('image', root.nsmap): #for some reason I can't get this to work...
print(img)
#we have to translate xlink: to {http://www.w3.org/1999/xlink} for it to work, despit the lib returning xlink: ...
settableAttributes = dict(img.items()) #img.attribute
settableAttributes['{http://www.w3.org/1999/xlink}href'] = settableAttributes['xlink:href']
del settableAttributes['xlink:href']
print(etree.tostring(img.makeelement('use', settableAttributes)))
- How do I iterate over all image tags, with tree.iterfind and a namsepace map?
for img in root.iterfind('image', namespaces=root.nsmap):
- I am trying to turn image tags into use tags. While lxml gives me an attribute dictionary with xlinx:href it chokes on passing this to makeelement is there an elegant solution?
这些都适合我:
img.makeelement('use', dict(img.items())
img.makeelement('use', img.attrib)
- Should I use lxml or is there something better (more straight forward)?
每个人都有意见。我喜欢 lxml。我觉得很简单。您的意见可能不同。
完整的程序:
from lxml import etree
def inlineSvg(path):
parser = etree.XMLParser(recover=True)
tree = etree.parse(path, parser)
root = tree.getroot()
for img in root.iterfind('image', namespaces=root.nsmap):
use = img.makeelement('use', img.attrib, nsmap=root.nsmap)
print(etree.tostring(use))
inlineSvg('xx.svg')
输入文件(xx.svg
):
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" height="130" width="500" style="fill: #000000"/>
<image x="20" y="20" width="300" height="80"
xlink:href="http://jenkov.com/images/layout/top-bar-logo.png" />
<line x1="25" y1="80" x2="350" y2="80"
style="stroke: #ffffff; stroke-width: 3;"/>
</svg>
结果:
$ python xx.py
b'<use xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" height="80" width="300" x="20" y="20" xlink:href="http://jenkov.com/images/layout/top-bar-logo.png"/>'
参考:
我正在尝试使用 lxml
进行 svg 解析并与命名空间作斗争。
问题:
- 如何使用
tree.iterfind
和名称空间映射遍历所有image
标签?tree.iterfind('image', root.nsmap)
不重新调整任何东西,更丑陋的tree.iter('{http://www.w3.org/2000/svg}image')
有效 - 我正在尝试将
image
标签转换为use
标签。虽然 lxml 给了我一个带有xlinx:href
的属性字典,但它在将它传递给makeelement
时会窒息,有没有优雅的解决方案? - 我应该使用
lxml
还是有更好的(更直接的)?我的目标是将image
标签重写为use
标签并将引用的 svgs 的内容嵌入到符号中。 (到目前为止lxml
我对命名空间的问题似乎令人厌恶)。
.
from lxml import etree
def inlineSvg(path):
parser = etree.XMLParser(recover=True)
tree = etree.parse(path, parser)
root = tree.getroot()
print(root.nsmap)
for img in tree.iter('{http://www.w3.org/2000/svg}image'):
#for img in tree.iterfind('image', root.nsmap): #for some reason I can't get this to work...
print(img)
#we have to translate xlink: to {http://www.w3.org/1999/xlink} for it to work, despit the lib returning xlink: ...
settableAttributes = dict(img.items()) #img.attribute
settableAttributes['{http://www.w3.org/1999/xlink}href'] = settableAttributes['xlink:href']
del settableAttributes['xlink:href']
print(etree.tostring(img.makeelement('use', settableAttributes)))
- How do I iterate over all image tags, with tree.iterfind and a namsepace map?
for img in root.iterfind('image', namespaces=root.nsmap):
- I am trying to turn image tags into use tags. While lxml gives me an attribute dictionary with xlinx:href it chokes on passing this to makeelement is there an elegant solution?
这些都适合我:
img.makeelement('use', dict(img.items())
img.makeelement('use', img.attrib)
- Should I use lxml or is there something better (more straight forward)?
每个人都有意见。我喜欢 lxml。我觉得很简单。您的意见可能不同。
完整的程序:
from lxml import etree
def inlineSvg(path):
parser = etree.XMLParser(recover=True)
tree = etree.parse(path, parser)
root = tree.getroot()
for img in root.iterfind('image', namespaces=root.nsmap):
use = img.makeelement('use', img.attrib, nsmap=root.nsmap)
print(etree.tostring(use))
inlineSvg('xx.svg')
输入文件(xx.svg
):
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" height="130" width="500" style="fill: #000000"/>
<image x="20" y="20" width="300" height="80"
xlink:href="http://jenkov.com/images/layout/top-bar-logo.png" />
<line x1="25" y1="80" x2="350" y2="80"
style="stroke: #ffffff; stroke-width: 3;"/>
</svg>
结果:
$ python xx.py
b'<use xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" height="80" width="300" x="20" y="20" xlink:href="http://jenkov.com/images/layout/top-bar-logo.png"/>'
参考: