简体   繁体   中英

Using namespaces in lxml

I am trying to do svg parsing with lxml and struggle with namespaces.

Questions:

  1. How do I iterate over all image tags, with tree.iterfind and a namsepace map? tree.iterfind('image', root.nsmap) does not retun anything, the uglier tree.iter('{http://www.w3.org/2000/svg}image') works
  2. 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?
  3. Should I use lxml or is there something better (more straight forward)? My goal is to rewrite image tags to use tags and embed the content of the referenced svgs in symbols. (So far lxml and the issues I had with namespaces seem repulsive).

.

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?

Either of these works for me:

img.makeelement('use', dict(img.items())
img.makeelement('use', img.attrib)
  • Should I use lxml or is there something better (more straight forward)?

Everybody's got an opinion. I like lxml. I find it very straightforward. Your opinion may differ.


Complete program:

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')

Input file ( 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>

result:

$ 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"/>'

Reference:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM