簡體   English   中英

如何使用Python在SVG文件中通過'id'字段查找元素

[英]How to find elements by 'id' field in SVG file using Python

以下是.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元素,其id字段等於libcode-XX ,其中XX是一個數字。

我使用minidom的解析器加載了這個.svg文件,並嘗試使用getElementById查找元素。 但是我收到了None結果。

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

繼續其他問題我已經嘗試在svgTemplate對象上使用setIdAttribute('id')而沒有運氣。

結論:請提示一個聰明的方法來提取所有這些具有libcode-XX形式的idtext元素。 之后,獲取tspan文本並將其替換為生成的內容應該沒有問題。

對不起,我不知道我在minidom周圍的路。 此外,我必須從示例svg文檔中找到命名空間聲明,以便您的摘錄可以加載。

我個人使用lxml.etree。 我建議您使用XPATH來處理XML文檔的部分內容。 這是非常強大的,如果你正在努力,那么在這里有幫助。

有關XPATH和etree的SO有很多答案。 我寫過幾篇。

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))

如果用'xml:id'替換'id',它會起作用嗎?

如果minidom不知道svg,它可能會將'id'屬性視為任何其他屬性,而不是類型ID。 符合svg的實現會將svg內容中的'id'屬性識別為ID類型,並且如果文件被正確標記,則加載外部DTD的xml實現也應該正確識別它。 在XML中加載外部DTD是可選的,因此修復此問題的正確方法是使解析器具有svg感知能力。

SVG 1.1 DTD中'id'的定義: http//www.w3.org/TR/SVG11/svgdtd.html#DTD.1.4

在使用xpath時添加一點MattH的一個很好的例子,你知道命名空間,你可以做的事情

pub_name = data.xpath('//dc:publisher/cc:Agent/dc:title',
                            namespaces=nsmap)[0].text

這將直接訪問您想要的元素標記文本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM