Getting AttributeError: 'Node' object has no attribute 'xml_tree' when parsing svg
When I try to run svg2png on this SVG from the yr.no weather symbols I get the following error.
SVG
<svg x="0" y="0" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">;
<symbol id="raindrop">
<path fill="#0062bf" d="M2.5,13A2.5,2.5,0,0,1,.21,9.51l3.55-8a2.5,2.5,0,0,1,4.57,2l-3.55,8A2.5,2.5,0,0,1,2.5,13Z"></path>
</symbol>
<symbol id="cloud">
<path d="M55.7,5A23.94,23.94,0,0,0,34.37,18.05a9.9,9.9,0,0,0-12.78,5.56,15,15,0,0,0-1.71-.1A14.81,14.81,0,0,0,9.2,28,14.63,14.63,0,0,0,5,38.17v.21A14.83,14.83,0,0,0,19.88,53.06H75.59a14.3,14.3,0,0,0,3.67-28.14A23.93,23.93,0,0,0,55.7,5Z"></path>
<image x="5" y="14" width="85" height="43" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFYAAAAkCAMAAAAkYj0PAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAVUExURSgoKExpcaCgoFBQUG5ublBQUISEhI1fsT0AAAAHdFJOUxsACBsPFRpGXuFgAAABWElEQVRIx7XV25bDIAgF0BMu/v8nF/E+iWlqHNKVN3cpIMXxL4GFM3SQfTazkUyxk63oLYwlVSy2silXkS/wUrZS2a3ZCn1zsdSw7UUYijuHsTa1IvfwWrbSXLkc4N9r27JViwmM1UtWXA3hohQ41m6vl8FQZi7wu2z7KXPW4uRiZS+2AmdXN7DdQEQWQHYHlt6z0dXBBa2xeeVktiZc1jDoF5eGkI4d4MjKc7cNbZ3bqjocLLx5oPDYTaIftcfvAvcs2GFxVsJTOP1wO1jGdUSLaz/DWA1Tl45+Tkqul2ArcPzayGq8JafOUffP3TUp6JQs+Rptc6vtmtBkUw+dv0NzWG0PYf8O7Ym09+ITXyXOPZqEX95aFe3PKxRsL2XV3HR+ZALirPSF0ceHp6F51WBv1A22VaW2GHWzWvat8LOAPf4CrjrA+neNK7+PQBf/DmmLrId09/QDWyESBsibwBUAAAAASUVORK5CYII="></image>
</symbol>
<symbol id="s09">
<use xlink:href="#cloud" fill="#b2b2b2" x="0" y="0" width="100" height="100" transform="translate(3,18) scale(1,1)"></use>
<use xlink:href="#raindrop" x="0" y="0" width="100" height="100" transform="translate(32,78) scale(1,1)"></use>
<use xlink:href="#raindrop" x="0" y="0" width="100" height="100" transform="translate(45,87) scale(1,1)"></use>
<use xlink:href="#raindrop" x="0" y="0" width="100" height="100" transform="translate(60,78) scale(1,1)"></use>
</symbol>
<symbol id="sun">
<path class="sun-glow" fill="url(#sun-glow-grad)" d="M66.64,47.86,82,41,66.64,34.12l9.84-13.66L59.76,22.22,61.46,5.47l-13.6,9.89L41,0,34.12,15.36,20.46,5.52l1.76,16.72L5.47,20.54l9.89,13.6L0,41l15.36,6.83L5.52,61.54l16.72-1.76L20.54,76.53l13.6-9.89L41,82l6.83-15.36,13.66,9.84L59.78,59.76l16.75,1.69Z"></path>
<path class="sun-outer" fill="#ffd348" d="M19.28,53.5a25,25,0,1,0,9.15-34.16A25,25,0,0,0,19.28,53.5Z"></path>
<path class="sun-inner" fill="url(#sun-inner-grad)" d="M22.74,51.5a21,21,0,1,0,7.69-28.69A21,21,0,0,0,22.74,51.5Z"></path>
</symbol>
<defs>
<mask id="cloud_3_18_1_1_5">
<rect x="0" y="0" width="100" height="100" fill="white"></rect>
<use xlink:href="#cloud" fill="black" stroke="black" stroke-linejoin="round" stroke-width="10" x="0" y="0" width="100" height="100" transform="translate(3,18) scale(1,1)"></use>
</mask>
<radialGradient id="sun-glow-grad" cx="41" cy="41" r="41" gradientUnits="userSpaceOnUse">
<stop offset="54%" stop-color="#d6b849"/>
<stop offset="67%" stop-color="#ffce47"/>
<stop offset="100%" stop-color="#ffdb73"/>
</radialGradient>
<linearGradient id="sun-inner-grad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#ffaf22" />
<stop offset="100%" stop-color="#f09900" />
</linearGradient>
</defs>
<symbol id="s05d">
<g mask="url(#cloud_3_18_1_1_5)">
<use xlink:href="#sun" x="0" y="0" width="100" height="100" transform="translate(0,2) scale(0.7,0.7)"></use>
</g>
<use xlink:href="#s09" x="0" y="0" width="100" height="100"></use>
</symbol>
<use xlink:href="#s05d" x="0" y="0" width="100" height="100"></use>
</svg>
Error
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-17-75690ad38733> in <module>()
1 from IPython.display import Image
----> 2 Image(glyph.to_png(scale=5), retina=True)
~/metglyphs/__init__.py in to_png(self, scale)
68 """Convert to a png."""
69 return cairosvg.svg2png(bytestring=self.svg,
---> 70 scale=scale)
71
72 def to_np_array(self, scale=1):
/opt/conda/lib/python3.6/site-packages/cairosvg/__init__.py in <lambda>(*args, **kwargs)
43 # Two lambdas needed for the closure
44 lambda surface_type: lambda *args, **kwargs:
---> 45 surface_type.convert(*args, **kwargs))(_surface_type)
46 _name = 'svg2{}'.format(_output_format.lower())
47 _function.__name__ = _name
/opt/conda/lib/python3.6/site-packages/cairosvg/surface.py in convert(cls, bytestring, **kwargs)
136 output = write_to or io.BytesIO()
137 instance = cls(
--> 138 tree, output, dpi, None, parent_width, parent_height, scale)
139 instance.finish()
140 if write_to is None:
/opt/conda/lib/python3.6/site-packages/cairosvg/surface.py in __init__(self, tree, output, dpi, parent_surface, parent_width, parent_height, scale)
193 width, height, viewbox, scale, preserved_ratio(tree))
194 self.context.move_to(0, 0)
--> 195 self.draw(tree)
196
197 @property
/opt/conda/lib/python3.6/site-packages/cairosvg/surface.py in draw(self, node)
411 if display and node.tag not in INVISIBLE_TAGS:
412 for child in node.children:
--> 413 self.draw(child)
414
415 # Apply filter, mask and opacity
/opt/conda/lib/python3.6/site-packages/cairosvg/surface.py in draw(self, node)
351 if node.tag in TAGS:
352 try:
--> 353 TAGS[node.tag](self, node)
354 except PointError:
355 # Error in point parsing, do nothing
/opt/conda/lib/python3.6/site-packages/cairosvg/defs.py in use(surface, node)
376 tree['width'], tree['height'] = node['width'], node['height']
377
--> 378 surface.draw(tree)
379 node.get('fill', None)
380 node.get('stroke', None)
/opt/conda/lib/python3.6/site-packages/cairosvg/surface.py in draw(self, node)
411 if display and node.tag not in INVISIBLE_TAGS:
412 for child in node.children:
--> 413 self.draw(child)
414
415 # Apply filter, mask and opacity
/opt/conda/lib/python3.6/site-packages/cairosvg/surface.py in draw(self, node)
419 apply_filter_before_painting(self, node, filter_)
420 if mask in self.masks:
--> 421 paint_mask(self, node, mask, opacity)
422 else:
423 self.context.paint_with_alpha(opacity)
/opt/conda/lib/python3.6/site-packages/cairosvg/defs.py in paint_mask(surface, node, name, opacity)
162
163 from .surface import SVGSurface # circular import
--> 164 mask_surface = SVGSurface(mask_node, None, surface.dpi, surface)
165 surface.context.save()
166 surface.context.translate(x, y)
/opt/conda/lib/python3.6/site-packages/cairosvg/surface.py in __init__(self, tree, output, dpi, parent_surface, parent_width, parent_height, scale)
193 width, height, viewbox, scale, preserved_ratio(tree))
194 self.context.move_to(0, 0)
--> 195 self.draw(tree)
196
197 @property
/opt/conda/lib/python3.6/site-packages/cairosvg/surface.py in draw(self, node)
411 if display and node.tag not in INVISIBLE_TAGS:
412 for child in node.children:
--> 413 self.draw(child)
414
415 # Apply filter, mask and opacity
/opt/conda/lib/python3.6/site-packages/cairosvg/surface.py in draw(self, node)
351 if node.tag in TAGS:
352 try:
--> 353 TAGS[node.tag](self, node)
354 except PointError:
355 # Error in point parsing, do nothing
/opt/conda/lib/python3.6/site-packages/cairosvg/defs.py in use(surface, node)
363 tree = Tree(
364 url=href, url_fetcher=node.url_fetcher, parent=node,
--> 365 tree_cache=surface.tree_cache, unsafe=node.unsafe)
366
367 if not match_features(tree.xml_tree):
/opt/conda/lib/python3.6/site-packages/cairosvg/parser.py in __init__(self, **kwargs)
384 while root_parent.parent:
385 root_parent = root_parent.parent
--> 386 tree = root_parent.xml_tree
387 else:
388 if not bytestring:
AttributeError: 'Node' object has no attribute 'xml_tree'
Doing a little more digging it looks like the issue happens when converting an image which contains a <use> tag within a <mask> tag.
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/mask
Doing a little more digging it looks like the issue happens when converting an image which contains a
That's a bad bug, related to #161. 4903608 gives a better crash error, but doesn't fix the issue.
As a work around for now I found that running my svg's through a conversion service resulted in a non buggy image. Would be nice for this to be fixed properly though.