用Python替换SVG的内部内容

时间:2014-07-13 19:47:50

标签: python xml dom svg

我有一个svg模板,我正在复制和自定义为游戏创建几个不同的牌和牌。我想以编程方式(在Python中,最好)从每张卡的模板中更改元素。我似乎毫不费力地找到改变属性或css的方法,但是我找不到可以轻松解析现有svg并替换元素的库。

我的模板的svg看起来有点像这样:

<!--Square 2" Tile Template -->
<svg xmlns="http://www.w3.org/2000/svg" width="181" height="181">
    <text id="tile_text" y="90" width="100%" 
          style="text-align:center;font-family:Verdana;font-size:20">
        TEXT TO REPLACE
    </text>
</svg>

我查看了Python的lxmlxml.dom.minidom,但它们似乎都不支持像tile_text_element.innerHTML = "New Tile Name"这样的内容。帮助

编辑:

为了增加我的工作流程,我为每张卡创建了一堆个性化的svgs,然后通过inkscape批量渲染为pdf。

4 个答案:

答案 0 :(得分:1)

另一种方法是使用lxml,似乎工作,警告质量差的代码:

$ cat card.py
#!/usr/bin/env python

from lxml import etree

with open('card.svg') as card:
    root = etree.fromstring(card.read())

root.find('.//{http://www.w3.org/2000/svg}text').text = "foobar"
print etree.tostring(root)
$ python card.py
<svg xmlns="http://www.w3.org/2000/svg" width="181" height="181">
    <text id="tile_text" y="90" width="100%" style="text-align:center;font-family:Verdana;font-size:20">foobar</text>
</svg>

答案 1 :(得分:1)

您可以使用ETXPath或XPath,但这可能是:

from lxml import etree

SVGNS = u"http://www.w3.org/2000/svg"
svg = '''<!--Square 2" Tile Template -->
<svg xmlns="http://www.w3.org/2000/svg" width="181" height="181">
    <text id="tile_text" y="90" width="100%" 
          style="text-align:center;font-family:Verdana;font-size:20">
        TEXT TO REPLACE
    </text>
</svg>'''

xml_data = etree.fromstring(svg)
# We search for element 'text' with id='tile_text' in SVG namespace
find_text = etree.ETXPath("//{%s}text[@id='tile_text']" % (SVGNS))
# find_text(xml_data) returns a list
# [<Element {http://www.w3.org/2000/svg}text at 0x106185ab8>]
# take the 1st element from the list, replace the text
find_text(xml_data)[0].text = 'BLAHBLAH'
new_svg = etree.tostring(xml_data)
print new_svg

然后结果。

<svg xmlns="http://www.w3.org/2000/svg" width="181" height="181">
    <text id="tile_text" y="90" width="100%" 
          style="text-align:center;font-family:Verdana;font-size:20">BLAHBLAH</text>
</svg>

希望它有所帮助。

答案 2 :(得分:0)

您可以在没有Python,svg support parameters

的情况下执行此操作

所以你可以使用

<!--Square 2" Tile Template -->
<svg xmlns="http://www.w3.org/2000/svg" width="181" height="181">
    <text id="tile_text" y="90" width="100%" style="text-align:center;font-family:Verdana;font-size:20" content-value="param(label)">default</text>

并使用:

your.svg?label=New Tile Name

请注意,w3.org上的工作示例模拟参数,因为并非每个浏览器都支持它,但您可以重用它们的模拟,但它们声明您不应该在生产中使用它:

  

请注意,这些示例是由Javascript原型模拟的。它   应该在Opera,Firefox和Safari以及其他人(Chrome?   插件?)。该脚本可以按原样使用,并在CC下发布   许可证,但它不是作为生产代码。内容作者   我们鼓励您尝试使用此代码,并对SVG进行评论   工作组访问www-svg@w3.org,提出建议和批评意见   基于经验的规范。

答案 3 :(得分:0)

我认为你可以在text属性为Element的lxml中执行此操作:

Elements contain text

>>> root = etree.Element("root")
>>> root.text = "TEXT"

>>> print(root.text)
TEXT

>>> etree.tostring(root)
b'<root>TEXT</root>'