使用BeautifulSoup修改SVG文件时,为什么文本对象会被更改?

时间:2017-04-19 19:44:02

标签: python python-3.x svg beautifulsoup inkscape

我在python3中使用BeautifulSoup模块来修改我用Inkscape创建的一些svg文件。具体来说,我正在修改这些文件中的一些文本,在某些情况下,还会更改某些对象的颜色。我注意到,无论我做什么,所有文本的位置总是在输出svg文件中移位。 例如,请参阅: svg in/out files + png versions

与原始文件相比,输出svg中文本对象的大小不同,似乎发生了什么。我可以将文本对象从输出文件复制到原始文件,我不再看到移位,但这是一个烦人的解决方案。

是否有人知道导致文本对象大小更改的原因是什么?是否可以阻止?

以下是我运行的代码示例(输入和输出svgs的副本位于上面的链接中):

from bs4 import BeautifulSoup

svgFile = "test_in.svg"
outputFile = "test_out.svg"

svg = open(svgFile, 'r').read()
soup = BeautifulSoup(svg, features = 'xml')
texts = soup.findAll('text')

for t in texts:
    if t['id'] == 'testID':
        print(t, '\n')
        t.contents[0].string = 'new text'
        print(t, '\n')

# Output the edited SVG file
f = open(outputFile, "w")
f.write(soup.prettify())
f.close()

xml / svg树中的文本元素似乎没有任何变化,所以我觉得问题必须来自对文件其他部分的更改。 (另外,我可以省略t.contents[0].string = 'new text',文本移动仍然会发生。)第一个print(t)给出:

<text id="testID" inkscape:label="#text3581" sodipodi:linespacing="125%" style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial" transform="matrix(0,1,-1,0,0,0)" x="449.63721" xml:space="preserve" y="-280.92737"><tspan id="tspan3583" sodipodi:role="line" style="font-size:14px;font-weight:normal;-inkscape-font-specification:Arial" x="449.63721" y="-280.92737">Text to change</tspan></text>

第二次打印(t)的输出似乎完全相同,除了'text to change'现在是'new text'

<text id="testID" inkscape:label="#text3581" sodipodi:linespacing="125%" style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial" transform="matrix(0,1,-1,0,0,0)" x="449.63721" xml:space="preserve" y="-280.92737"><tspan id="tspan3583" sodipodi:role="line" style="font-size:14px;font-weight:normal;-inkscape-font-specification:Arial" x="449.63721" y="-280.92737">new text</tspan></text> 

任何见解都将不胜感激!

2 个答案:

答案 0 :(得分:1)

我有同样的问题。问题是,当bs4解析文件时,它会将文本内容添加到新行中,因此在文本之前和之后会添加额外的空格,这就是它在svg内部移位的原因。

以下是输入svg文件的屏幕截图。您看到文本与标记位于同一行

enter image description here

在输出svg文件(如下)上,您将看到在bs4解析后,“新文本”内容与标记位于不同的行。还发生的事情是,在文本背景之前和之后现在有很多空白区域,这是导致其位置在svg图像中移位的原因。我刚刚遇到这个问题,还不确定解决方案是什么。

enter image description here

答案 1 :(得分:1)

正在发生的事情是您通过插入换行符并调用prettify()来添加额外的空格。

   <tspan id="tspan3583" sodipodi:role="line" style="font-size:14px;font-weight:normal;-inkscape-font-specification:Arial" x="449.63721" y="-280.92737">
    new text
   </tspan>

“新文本”之前有四个额外的空格。

通常这不会有问题。默认情况下,XML中会删除元素开头的空格。不幸的是,您的SVG文件在文本元素中具有以下属性:

xml:space="preserve"

这告诉浏览器你关心这些空格,并希望它们被保存和显示。

您有两种解决方案:

  1. 停止添加换行符和/或美化
  2. 检查并删除目标文本元素中的所有xml:space属性。或者将值从"preserve"更改为"default"