0
votes

Supprimer l'élément SVG basé sur le texte

J'ai un fichier SVG. J'essaie de me débarrasser de certains éléments contenant du texte spécifique: xxx pré>

L'exemple ci-dessus illustre ce que je dois faire: je devrais supprimer tout le bloc ( ... g> g> code>) car il contient somespecificextext code> et somespecificextbis code>. Je dois le faire pour tout "bloc" ou "élément" contenant l'un ou l'autre texte. P>

Je veux atteindre cet article en utilisant Python et LXML car apparemment, cela fournit les outils nécessaires, mais je n'ai pas 't sais comment l'utiliser. J'ai ce code pour le moment: p> xxx pré>

mais je ne sais pas quelle méthode je utiliserai? J'ai vu certains parler de xpath et j'ai essayé par ex. arbores.xpath ('.// ​​g [contient (texte (), "somespecific")]) code> mais il renvoie une liste vide. p>

edit forte > p>

J'ai essayé ce qui suit, d'essayer d'attraper la structure qui détient "SomespecificText" (correspondance partielle requise), mais elle renvoie toujours une liste vide pour Parents Code> P> P>

<?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 commentaires

Il y a une bonne chance que votre tentative XPath ne fonctionne pas car SVG est généralement dans un espace de noms par défaut. Essayez Réponse de Jack ci-dessous et si cela ne fonctionne pas, ajoutez la balise de démarrage SVG complète (ou idéalement, un minimum mais complet SVG afin que nous puissions dupliquer) à votre question.


Malheureusement, je ne peux pas mettre le SVG entier car il contient de nombreuses données sensibles et je ne peux pas prendre le temps de le rendre anonyme. J'ai essayé la solution mais cela ne fonctionne pas. Je vais mettre à jour mon post pour indiquer ce que j'ai essayé


Dans votre édition, vous avez correctement lié le préfixe "SVG", mais vous ne l'avez pas utilisé dans votre XPath. De plus, texte est un élément afin d'utiliser texte () dans votre contient () ne fonctionnera pas. Voici comment je le ferais: cibles = tree.xpath ( '// svg: g [./ svg: g [.// svg:. Texte [contient ( "SomeSpec ificText")]]] [.//svg: Texte [Contient (., "SO MESPECIFICTEXTBIS")]]] '', des espaces de noms = {"SVG": "http://www.w3.org/2000/svg"}) < / code> (le .// n'était généralement pas nécessaire, mais je ne sélectionne rien sans eux)


3 Réponses :


0
votes

Vous pouvez utiliser une belle soupe 4 et Python 3 pour y accomplir. Dans votre exemple, ce code fera:

#!/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)


0 commentaires

1
votes

Vous pouvez certainement le faire avec 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())    


0 commentaires

1
votes

J'ai trouvé la voie à effectuer la tâche:

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 commentaires