J'ai un fichier SVG. J'essaie de me débarrasser de certains éléments contenant du texte spécifique: L'exemple ci-dessus illustre ce que je dois faire: je devrais supprimer tout le bloc ( 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> mais je ne sais pas quelle méthode je utiliserai? J'ai vu certains parler de xpath et j'ai essayé par ex. 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
somespecificextext code> et
somespecificextbis code>. Je dois le faire pour tout "bloc" ou "élément" contenant l'un ou l'autre texte. P>
arbores.xpath ('.// g [contient (texte (), "somespecific")]) code> mais il renvoie une liste vide. p>
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 Réponses :
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)
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())
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))
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 code> est un élément afin d'utiliser
texte () code> 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
.// code> n'était généralement pas nécessaire, mais je ne sélectionne rien sans eux)