如何使用Python在SVG文件中通过'id'字段查找元素 [英] How to find elements by 'id' field in SVG file using Python
问题描述
以下是.svg文件(这是xml)的摘录:
Below is an excerpt from an .svg file (which is xml):
<text
xml:space="preserve"
style="font-size:14.19380379px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono"
x="109.38555"
y="407.02847"
id="libcode-00"
sodipodi:linespacing="125%"
inkscape:label="#text4638"><tspan
sodipodi:role="line"
id="tspan4640"
x="109.38555"
y="407.02847">12345678</tspan></text>
我正在学习Python,不知道如何找到所有这样的文本
元素具有 id
字段等于 libcode-XX
其中XX是一个数字
I'm learning Python and have no clue how can I find all such text
elements that have an id
field equal to libcode-XX
where XX is a number.
我使用minidom的解析器加载了这个.svg文件,并尝试使用 getElementById
找到元素。但是我得到无
结果。
I've loaded this .svg file using minidom's parser and tried to find elements using getElementById
. However I'm getting None
result.
svgTemplate = minidom.parse(svgFile)
print svgTemplate
print svgTemplate.getElementById('libcode-00')
在其他SO问题之后,我尝试在 svgTemplate
对象中使用 setIdAttribute('id')
Going after other SO question I've tried using setIdAttribute('id')
on svgTemplate
object with no luck.
底线:请提供一个聪明的方法来提取所有这些文本
元素, id
的形式为 libcode-XX
。之后,得到 tspan
文本并用生成的内容替代它应该是没问题的。
Bottom line: please give a hint for a smart way to extract all of these text
elements that have id
s in form of libcode-XX
. After that it should be no problem to get tspan
text and substitute it with generated content.
推荐答案
对不起,我不知道我在minidom的方式。此外,我不得不从一个示例svg文档中找到命名空间声明,以便您的摘录可以加载。
Sorry, I don't know my way around minidom. Also, I had to find the namespace declarations from a sample svg document so that your excerpt could load.
我个人使用lxml.etree。我建议您使用XPATH来处理XML文档的部分内容。它非常强大,如果你正在努力,这里有帮助。
I personally use lxml.etree. I'd recommend that you use XPATH for addressing parts of your XML document. It's pretty powerful and there's help here on SO if you're struggling.
有关XPATH和etree的许多答案。我已经写了几个。
There are lots of answers on SO about XPATH and etree. I've written several.
from lxml import etree
data = """
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="50"
height="25"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.45.1"
version="1.0"
sodipodi:docbase="/home/tcooksey/Projects/qt-4.4/demos/embedded/embeddedsvgviewer/files"
sodipodi:docname="v-slider-handle.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<text
xml:space="preserve"
style="font-size:14.19380379px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Sans Mono;-inkscape-font-specification:DejaVu Sans Mono"
x="109.38555"
y="407.02847"
id="libcode-00"
sodipodi:linespacing="125%"
inkscape:label="#text4638"><tspan
sodipodi:role="line"
id="tspan4640"
x="109.38555"
y="407.02847">12345678</tspan></text>
</svg>
"""
nsmap = {
'sodipodi': 'http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd',
'cc': 'http://web.resource.org/cc/',
'svg': 'http://www.w3.org/2000/svg',
'dc': 'http://purl.org/dc/elements/1.1/',
'xlink': 'http://www.w3.org/1999/xlink',
'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'inkscape': 'http://www.inkscape.org/namespaces/inkscape'
}
data = etree.XML(data)
# All svg text elements
>>> data.xpath('//svg:text',namespaces=nsmap)
[<Element {http://www.w3.org/2000/svg}text at b7cfc9dc>]
# All svg text elements with id="libcode-00"
>>> data.xpath('//svg:text[@id="libcode-00"]',namespaces=nsmap)
[<Element {http://www.w3.org/2000/svg}text at b7cfc9dc>]
# TSPAN child elements of text elements with id="libcode-00"
>>> data.xpath('//svg:text[@id="libcode-00"]/svg:tspan',namespaces=nsmap)
[<Element {http://www.w3.org/2000/svg}tspan at b7cfc964>]
# All text elements with id starting with "libcode"
>>> data.xpath('//svg:text[fn:startswith(@id,"libcode")]',namespaces=nsmap)
[<Element {http://www.w3.org/2000/svg}text at b7cfcc34>]
# Iterate text elements, access tspan child
>>> for elem in data.xpath('//svg:text[fn:startswith(@id,"libcode")]',namespaces=nsmap):
... tp = elem.xpath('./svg:tspan',namespaces=nsmap)[0]
... tp.text = "new text"
open("newfile.svg","w").write(etree.tostring(data))
这篇关于如何使用Python在SVG文件中通过'id'字段查找元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!