为什么在使用 BeautifulSoup 修改 SVG 文件时文本对象会发生变化?
Why are text objects altered when modifying SVG files with BeautifulSoup?
我正在使用 python3 中的 BeautifulSoup 模块来修改我使用 Inkscape 创建的一些 svg 文件。具体来说,我修改了这些文件中的一些文本,在某些情况下,还更改了一些对象的颜色。我注意到,无论我做什么,所有文本的位置总是在输出 svg 文件中移动。 例如见: svg in/out files + png versions
似乎发生的事情是输出 svg 中文本对象的大小与原始文件不同。我可以将文本对象从输出文件复制到原始文件,我不再看到转换,但这是一个烦人的解决方案。
有谁知道是什么导致了文本对象大小的这种变化,是否可以阻止这种变化?
这是我的一段代码示例 运行(输入和输出 svg 的副本位于上面的 link):
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>
第二个 print(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>
如有任何见解,我们将不胜感激!
我遇到了同样的问题。问题是,当 bs4 解析文件时,它会将文本内容添加到新行中,因此在文本前后添加了额外的白色space,这就是它在 svg 内部移动的原因。
这是您输入的 svg 文件的屏幕截图。您会看到文本与标签在同一行
在您的输出 svg 文件(下方)中,您会看到在 bs4 解析之后,'new text' 内容与标签位于不同的行中。还发生的是,现在文本内容前后有很多白色 space,这是导致其在 svg 图像中的位置发生变化的原因。我现在也遇到这个问题,不知道怎么解决。
实际情况是您通过插入换行符并调用 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>
"new text"前多了四个空格。
通常这不是问题。默认情况下,在 XML 中,元素开头的空格会被删除。不幸的是,您的 SVG 文件在文本元素中具有以下属性:
xml:space="preserve"
这会告诉浏览器您关心这些空格,并且您希望保留和显示它们。
你有两个解决方案:
- 停止添加换行符and/or美化
- 检查并删除目标文本元素中的任何
xml:space
属性。或者将值从 "preserve"
更改为 "default"
。
我正在使用 python3 中的 BeautifulSoup 模块来修改我使用 Inkscape 创建的一些 svg 文件。具体来说,我修改了这些文件中的一些文本,在某些情况下,还更改了一些对象的颜色。我注意到,无论我做什么,所有文本的位置总是在输出 svg 文件中移动。 例如见: svg in/out files + png versions
似乎发生的事情是输出 svg 中文本对象的大小与原始文件不同。我可以将文本对象从输出文件复制到原始文件,我不再看到转换,但这是一个烦人的解决方案。
有谁知道是什么导致了文本对象大小的这种变化,是否可以阻止这种变化?
这是我的一段代码示例 运行(输入和输出 svg 的副本位于上面的 link):
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>
第二个 print(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>
如有任何见解,我们将不胜感激!
我遇到了同样的问题。问题是,当 bs4 解析文件时,它会将文本内容添加到新行中,因此在文本前后添加了额外的白色space,这就是它在 svg 内部移动的原因。
这是您输入的 svg 文件的屏幕截图。您会看到文本与标签在同一行
在您的输出 svg 文件(下方)中,您会看到在 bs4 解析之后,'new text' 内容与标签位于不同的行中。还发生的是,现在文本内容前后有很多白色 space,这是导致其在 svg 图像中的位置发生变化的原因。我现在也遇到这个问题,不知道怎么解决。
实际情况是您通过插入换行符并调用 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>
"new text"前多了四个空格。
通常这不是问题。默认情况下,在 XML 中,元素开头的空格会被删除。不幸的是,您的 SVG 文件在文本元素中具有以下属性:
xml:space="preserve"
这会告诉浏览器您关心这些空格,并且您希望保留和显示它们。
你有两个解决方案:
- 停止添加换行符and/or美化
- 检查并删除目标文本元素中的任何
xml:space
属性。或者将值从"preserve"
更改为"default"
。