Удалить элемент SVG на основе текста - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть файл SVG. Я пытаюсь избавиться от некоторых элементов, содержащих указанный c текст:

<g style="font-family:'ARIAL'; stroke:none; fill:rgb(127,0,0);" >
<g font-size="53.4132" >
<text id="cv_126" x="168" y="474.78" transform="rotate(330 168 474.78) translate(168 -474.78) scale(1 1) translate(-168 474.78) ">SomeSpecificText</text>
<text id="cv_127" x="336" y="474.78" transform="rotate(330 336 474.78) translate(336 -474.78) scale(1 1) translate(-336 474.78) ">SomeSpecificTextBis</text>
</g>
</g>

. Приведенный выше пример иллюстрирует то, что мне нужно сделать: мне нужно удалить весь блок (<g><g> ... </g></g>), потому что он содержит SomeSpecificText и SomeSpecificTextBis. Я должен сделать это для любого "блока" или "элемента", который содержит либо тот, либо другой текст.

Я хочу добиться этого, используя Python и l xml, потому что, очевидно, это обеспечивает необходимый инструменты, но я не знаю, как его использовать. У меня есть этот код на данный момент:

tree = etree.parse(open("myFile.svg"))

, но тогда я не знаю, какой метод я буду использовать? Я видел, как кто-то говорил о xpath и пытался, например, tree.xpath('.//g[contains(text(), "SomeSpecific")]), но он возвращает пустой список.

EDIT

Я пробовал следующее, чтобы попытаться поймать структура, которая содержит «someSpecificText» (требуется частичное совпадение), но она по-прежнему возвращает пустой список для parents

tree = etree.parse(open("svg/myFile_ezdxf.svg"))
targets = tree.xpath('//g[./g[contains(text(),"SomeText")]]', namespaces = {"svg" : "http://www.w3.org/2000/svg"})
for target in targets:
    target.getparent().remove(target)

Также вот заголовок моего файла SVG:

<?xml version="1.0" encoding="utf-8" ?>
<!-- Generated by SomeCompanySoftware -->
<!-- www.somecompany.com -->
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 
'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
<svg contentScriptType="text/ecmascript" xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify" 
contentStyleType="text/css" preserveAspectRatio="xMidYMid meet" 
width="840" height="593.48" viewBox="0 0 840 593.48" 
version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:cvjs="http://www.somecompany.com/" stroke-linecap="round" stroke-linejoin="round" fill-rule="evenodd" >

Ответы [ 3 ]

1 голос
/ 03 февраля 2020

Вы определенно можете сделать это с помощью l xml:

targets = tree.xpath('//g[./g[text="SomeSpecificTextBis" or text="SomeSpecificText"]]')
for target in targets:
    target.getparent().remove(target)
print(etree.tostring(tree, pretty_print=True).decode())    
0 голосов
/ 05 февраля 2020

Я нашел способ выполнить задачу:

tree = etree.parse(open("myFile.svg"))
root = tree.getroot()
targets = ["SomeText", "SomeText2"]
for element in root.iter("*"):
   if (element.text is not None) and any([item in element.text for item in targets]):
      element.getparent().remove(element)
with open('myModifiedFile.svg', 'wb') as f:
    f.write(etree.tostring(tree))
0 голосов
/ 03 февраля 2020

Вы можете использовать Прекрасный Суп 4 и Python 3, чтобы выполнить sh это. В вашем примере этот код будет делать:

#!/usr/local/bin/python3
from bs4 import BeautifulSoup

tree = BeautifulSoup(open('svg.svg').read(),features="lxml")

for item in tree.find_all(): 
    if item.getText().strip() == "SomeSpecificText" or item.getText().strip() == "SomeSpecificText" :
        item.findParent().findParent().decompose()

print(tree)

Это немного хрупко, хотя я не знаю ваших точных логик c, но вы можете улучшить его.

...