在lxml中使用命名空间

4

我正在尝试使用 lxml 进行 SVG 解析,并且在命名空间方面遇到了困难。

问题:

  1. 如何使用命名空间映射和 tree.iterfind 遍历所有 image 标签?tree.iterfind('image', root.nsmap) 不返回任何内容,而较丑的 tree.iter('{http://www.w3.org/2000/svg}image') 可以正常工作。
  2. 我正在尝试将 image 标签转换为 use 标签。虽然 lxml 给了我一个带有 xlinx:href 属性字典,但将其传递给 makeelement 时会出错,是否有更优雅的解决方案?
  3. 我应该使用 lxml 还是有更好(更直接)的工具?我的目标是将 image 标签重写为 use 标签,并在符号中嵌入引用的 svg 的内容。(到目前为止,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)))
1个回答

3
如何使用tree.iterfind和命名空间映射迭代所有图像标签?
for img in root.iterfind('image', namespaces=root.nsmap):

我正在尝试将图像标签转换为使用标签。虽然lxml给了我一个带有xlinx:href属性字典,但在将其传递给makeelement时却出现问题,是否有更优雅的解决方案?
我两种方法都可以使用:
img.makeelement('use', dict(img.items())
img.makeelement('use', img.attrib)
  • 我应该使用lxml还是有更好的选择(更直接的)?

每个人都有自己的看法。我喜欢使用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"/>'

参考资料:


很好的一般性回答。我认为img.makeelement('use', img.attrib)不起作用的问题在于我的svg文件缺少xmlns:xlink="http://www.w3.org/1999/xlink"。有没有办法我可以添加它? - ted
也许。请编辑您的问题,包括一个简短完整的SVG文件,以演示错误。 - Robᵩ
目前,我使用etree.register_namespace('xlink','http://www.w3.org/1999/xlink')解决了我的问题。由于我的一些问题可能与CentOS上的pipyum有关(动态库可能具有错误版本),我认为深入探究这个问题没有太大意义。但如果您仍然感兴趣,请查看此问题答案。它包含一个最小的SVG示例,并且是研究etree的原因,答案是结果。 - ted
由于脚本已经完成了工作,我只是有点想找到更好的方法来插入命名空间(因为我的解决方案很丑陋且硬编码)。 - ted

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接