删除基于文本的 SVG 元素
Delete SVG element based on text
我有一个 SVG 文件。我试图摆脱一些包含特定文本的元素:
<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
。我必须对包含一个或另一个文本的任何 "block" 或 "element" 执行此操作。
我想使用 Python 和 lxml 来实现这一点,因为显然,这提供了必要的工具,但我不知道如何使用它。我现在有这段代码:
tree = etree.parse(open("myFile.svg"))
但是我不知道应该使用哪种方法?我看过一些关于 xpath 的话题,并尝试过,例如tree.xpath('.//g[contains(text(), "SomeSpecific")])
但它 returns 是一个空列表。
编辑
我尝试了以下方法,试图捕获包含 "someSpecificText" 的结构(需要部分匹配),但它仍然 returns 是 parents
[=19= 的空列表]
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 文件的 header :
<?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" >
您可以使用 Beutiful Soup 4 和 Python 3 来完成此操作。
在您的示例中,此代码将执行:
#!/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)
虽然它有点脆弱,因为我不知道你的确切逻辑,但你可以改进它。
你绝对可以用 lxml 做到这一点:
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())
我找到了执行任务的方法:
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))
我有一个 SVG 文件。我试图摆脱一些包含特定文本的元素:
<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
。我必须对包含一个或另一个文本的任何 "block" 或 "element" 执行此操作。
我想使用 Python 和 lxml 来实现这一点,因为显然,这提供了必要的工具,但我不知道如何使用它。我现在有这段代码:
tree = etree.parse(open("myFile.svg"))
但是我不知道应该使用哪种方法?我看过一些关于 xpath 的话题,并尝试过,例如tree.xpath('.//g[contains(text(), "SomeSpecific")])
但它 returns 是一个空列表。
编辑
我尝试了以下方法,试图捕获包含 "someSpecificText" 的结构(需要部分匹配),但它仍然 returns 是 parents
[=19= 的空列表]
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 文件的 header :
<?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" >
您可以使用 Beutiful Soup 4 和 Python 3 来完成此操作。 在您的示例中,此代码将执行:
#!/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)
虽然它有点脆弱,因为我不知道你的确切逻辑,但你可以改进它。
你绝对可以用 lxml 做到这一点:
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())
我找到了执行任务的方法:
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))