python - 如何使用 Python 在 SVG 文件中按 'id' 字段查找元素

标签 python xml dom svg minidom

以下是 .svg 文件(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,但不知道如何找到所有 text 字段等于 idlibcode-XX 元素,其中 XX 是一个数字。

我已经使用 minidom 的解析器加载了这个 .svg 文件,并尝试使用 getElementById 查找元素。但是我得到了 None 结果。

    svgTemplate = minidom.parse(svgFile)
    print svgTemplate
    print svgTemplate.getElementById('libcode-00')

追寻其他 SO 问题,我尝试在 setIdAttribute('id') 对象上使用 svgTemplate 但没有成功。

底线:请提供一种聪明的方法来提取所有这些 text 元素,这些元素具有 id 形式的 libcode-XX 。之后获取 tspan 文本并将其替换为生成的内容应该没有问题。

最佳答案

抱歉,我不了解 minidom。此外,我还必须从示例 svg 文档中找到命名空间声明,以便可以加载您的摘录。

我个人使用 lxml.etree。我建议您使用 XPATH 来寻址您的 XML 文档的各个部分。它非常强大,如果您遇到困难,可以在 SO 上找到帮助。

SO 上有很多关于 XPATH 和 etree 的答案。我写了好几篇。

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 - 如何使用 Python 在 SVG 文件中按 'id' 字段查找元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2359317/

相关文章:

html - HTML 解析期间范围发生变化

javascript - Angular2 setinterval 在 dom 更改时被阻止

python - Pyaudio 如何仅在一个扬声器上播放声音

python - more_like_this 多个索引的elasticsearch查询

javascript - gauge.js - 相对 URL 不起作用,但绝对 URL 在 Django 1.10 中起作用

jquery - 如何使用CakePHP和jQuery实现跨域Ajax请求?

javascript - 根据所选值显示输入按钮

python - 使用 beautifulsoup 从维基百科表中获取列

c# - 使用 XmlSerializer 读取 XML 文件后,我的所有 IsDirty 标志都设置为 true

xml - xslt:无法识别 2 参数函数