如何使用Python在SVG文件中通过'id'字段查找元素 [英] How to find elements by 'id' field in SVG file using Python

查看:340
本文介绍了如何使用Python在SVG文件中通过'id'字段查找元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是.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 ids 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆