I am trying to do svg parsing with lxml
and struggle with namespaces.
Questions:
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')
worksimage
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?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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With