Gestion des données xml d'un fichier .svg

Résolu
peter76960 Messages postés 11 Date d'inscription vendredi 24 novembre 2023 Statut Membre Dernière intervention 22 juillet 2024 - Modifié le 27 nov. 2023 à 14:52
mamiemando Messages postés 33284 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 25 septembre 2024 - 5 déc. 2023 à 16:02

Bonjour

Je souhaiterai récupérer les données xml de mon fichier.svg. J'ai réussi pour les attributs 'transform' et 'viewBox' mais pas ensemble 'du texte'. J'ai essayé pour item 10 sans succès, mais je souhaiterais obtenir les items 10 à 220. Je souhaiterais les associer aux valeurs de attribut 'transform'.

Si quelqu'un pouvait me donner une piste je serais honoré. Le but est obtenir :

matrix(1 0 0 1 107.4256 666.9805)   10
matrix(1 0 0 1 802.0038 652.9802)   30

etc...
actuellement; je n'ai que

matrix(1 0 0 1 107.4256 666.9805) 
matrix(1 0 0 1 802.0038 652.9802) 

Ensuite, je devrais réaliser un script pour conserver  uniquement info qui m'intéresse soit :

10   107.4256    666.9805
20 .....

puis les placer dans 3 colonnes d'un fichier excel.

from lxml import etree
import re
liste2D=[]

tree = etree.parse("C:/Users/Julien.VEYRES/Desktop/hotspot/77-68034-00-1.svg") # indiquer le chemin ou trouver les infos
                                                                               #  Tree, importante librairie permettant de naviguer et analyser(parse) un xml
ns = {'svg': 'http://www.w3.org/2000/svg'} # definir le namespace, le langage(xml) du SVG pour s'y retrouver
for lg in tree.findall(".//svg:text", ns):
    if 'transform' in lg.attrib:
        print(lg.attrib['transform'])
for lg in tree.findall("."):
    if 'viewBox' in lg.attrib:
        print(lg.attrib['viewBox'])
for lg in tree.findall("//svg:<text>", ns):
    if '10' in lg.balise:
        print(lg.balise['10'])
.....
text transform="matrix(1 0 0 1 107.4256 666.9805)" class="st1 st2">10</text>
<line class="st3" x1="792.3" y1="614.2" x2="650.6" y2="691.5"/>
<text transform="matrix(1 0 0 1 802.0038 652.9802)" class="st1 st2">30</text>
<line class="st0" x1="792.3" y1="649.2" x2="624.4" y2="740.5"/>
<text transform="matrix(1 0 0 1 800.244 619.3326)" class="st1 st2">20</text>
<line class="st3" x1="794.9" y1="555.9" x2="606.6" y2="658.7"/>
<text transform="matrix(1 0 0 1 798.3729 560.3386)" class="st1 st2">100</text>
<line class="st0" x1="263" y1="761" x2="140" y2="696.3"/>
<text transform="matrix(1 0 0 1 109.4681 699.9636)" class="st1 st2">70</text>
<line class="st0" x1="461.6" y1="779.2" x2="385.5" y2="772.9"/>
<text transform="matrix(1 0 0 1 466.3724 786.7623)" class="st1 st2">80</text>
<line class="st0" x1="792.3" y1="739.9" x2="685.6" y2="740.1"/>
<text transform="matrix(1 0 0 1 803.9842 746.106)" class="st1 st2">90</text>
<line class="st0" x1="846.2" y1="818.2" x2="716" y2="866.6"/>
<text transform="matrix(1 0 0 1 853.1932 822.8347)" class="st1 st2">60</text>
<path class="st0" d="M-35.3,34.3"/>
<path class="st0" d="M297.7,220"/>
<line class="st0" x1="92.9" y1="216" x2="20.7" y2="34.3"/>
<line class="st0" x1="968.1" y1="82.1" x2="664" y2="247.5"/>
<line class="st0" x1="971.6" y1="201.7" x2="845.3" y2="270.4"/>
<line class="st0" x1="655.9" y1="26.4" x2="529.6" y2="95"/>
<text transform="matrix(1 0 0 1 643.4149 18.414)" class="st1 st2">120</text>
<line class="st0" x1="439.2" y1="504.7" x2="439.6" y2="381.3"/>
<line class="st0" x1="198.7" y1="209.4" x2="139.1" y2="34.3"/>
<line class="st0" x1="166.4" y1="407.4" x2="166" y2="315"/>
<path class="st0" d="M783.3,255.4"/>
<path class="st0" d="M968.5,154.7"/>
<line class="st0" x1="874.3" y1="31.6" x2="513.6" y2="232.1"/>
<line class="st0" x1="976" y1="26.4" x2="590.3" y2="236.3"/>
<line class="st0" x1="431.3" y1="235.1" x2="698.1" y2="83.3"/>
<line class="st0" x1="308.5" y1="486" x2="307.9" y2="377.1"/>
<text transform="matrix(1 0 0 1 983.5477 207.6896)" class="st1 st2">130</text>
<text transform="matrix(1 0 0 1 1.9096 26.4328)" class="st1 st2">140</text>
<text transform="matrix(1 0 0 1 123.9148 26.4328)" class="st1 st2">220</text>
<line class="st0" x1="969.4" y1="124.7" x2="723.9" y2="258.5"/>
<text transform="matrix(1 0 0 1 983.5477 127.215)" class="st1 st2">190</text>
<text transform="matrix(1 0 0 1 983.5477 83.7648)" class="st1 st2">110</text>
<text transform="matrix(1 0 0 1 863.1507 21.9888)" class="st1 st2">150</text>
<text transform="matrix(1 0 0 1 422.2171 527.5231)" class="st1 st2">160</text>
<text transform="matrix(1 0 0 1 290.4154 509.5524)" class="st1 st2">200</text>
A voir également:

4 réponses

mamiemando Messages postés 33284 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 25 septembre 2024 7 787
1 déc. 2023 à 15:29

Bonjour,

Voici un code simplifié qui devrait répondre à ta question

import pandas as pd
import xml.etree.ElementTree as ET
from pprint import pprint

svg = """<?xml version="1.0"?>
<xml>
<text transform="matrix(1 0 0 1 983.5477 127.215)" class="st1 st2">190</text>
<text transform="matrix(1 0 0 1 983.5477 83.7648)" class="st1 st2">110</text>
<text transform="matrix(1 0 0 1 863.1507 21.9888)" class="st1 st2">150</text>
<text transform="matrix(1 0 0 1 422.2171 527.5231)" class="st1 st2">160</text>
<text transform="matrix(1 0 0 1 290.4154 509.5524)" class="st1 st2">200</text>
</xml>"""

tree = ET.ElementTree(ET.fromstring(svg))
records = list()
for node in tree.findall(".//text"):
    if "transform" in node.attrib:
        matrix = node.attrib["transform"]
        i = matrix.index("(") + 1
        j = matrix.index(")")
        record = [float(x) for x in matrix[i: j].split()]
        k = int(node.text)
        record.append(k)
        records.append(record)

pprint(records)
df = pd.DataFrame(records)
df

Résultat :

[[1.0, 0.0, 0.0, 1.0, 983.5477, 127.215, 190],
 [1.0, 0.0, 0.0, 1.0, 983.5477, 83.7648, 110],
 [1.0, 0.0, 0.0, 1.0, 863.1507, 21.9888, 150],
 [1.0, 0.0, 0.0, 1.0, 422.2171, 527.5231, 160],
 [1.0, 0.0, 0.0, 1.0, 290.4154, 509.5524, 200]]

Bonne chance

2
yg_be Messages postés 23228 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 septembre 2024 Ambassadeur 1 538
Modifié le 28 nov. 2023 à 03:01

bonjour,

suggestion:

from lxml import etree

# Indiquer le chemin ou trouver les infos
# lxml permet de naviguer et analyser(parse) un XML
tree = etree.parse("test.svg")

# Définir le namespace, le langage (XML)
# du SVG pour s'y retrouver
ns = {"svg": "http://www.w3.org/2000/svg"}
for lg in tree.findall(".//svg:text", ns):
    if "transform" in lg.attrib:
        attr = lg.attrib["transform"]
        print(lg.text, attr)
0
peter76960 Messages postés 11 Date d'inscription vendredi 24 novembre 2023 Statut Membre Dernière intervention 22 juillet 2024
Modifié le 27 nov. 2023 à 11:21

Bonjour

merci ca fonctionne, je n'avais pas pensé à faire
print(lg.text,....) certainement mon manque de logique et expérience avec Python.
Concernant le transfert de certaines de ses valeurs  dans un fichier xls, quelle méthode vous me suggérez?
Peut être passer de XML en CSV puis en XLS ? d'après ce que j'ai lu sur internet

cordialement

0
yg_be Messages postés 23228 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 septembre 2024 1 538 > peter76960 Messages postés 11 Date d'inscription vendredi 24 novembre 2023 Statut Membre Dernière intervention 22 juillet 2024
27 nov. 2023 à 13:00

Il est en effet très simple de créer un fichier CSV.

0
mamiemando Messages postés 33284 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 25 septembre 2024 7 787 > yg_be Messages postés 23228 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 septembre 2024
27 nov. 2023 à 14:54

Si tu utilises pandas, tu ne devrais pas avoir de difficulté à générer directement tes fichiers excel sans faire d'étape par un csv, mais plutôt par une pandas.DataFrame. Voir ici. Au lieu de faire des print, il faudra simplement peupler ta DataFrame.

0
peter76960 Messages postés 11 Date d'inscription vendredi 24 novembre 2023 Statut Membre Dernière intervention 22 juillet 2024 > mamiemando Messages postés 33284 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 25 septembre 2024
Modifié le 28 nov. 2023 à 03:02

Merci j'ai crée mon dataframe, mais je n'ai qu'une valeur prise en compte "matrix(1 0 0 1 686.7148 73.5248)  180". Je voudrais toute la liste de (lg.text,attr) de mon XML.

Des conseils? Pas de solution, une méthode à appliquer, s'il vous plaît.

Merci

for lg in tree.findall("//svg:text", ns):
    if 'transform' in lg.attrib:
        attr = lg.attrib['transform']
        print(lg.text, attr)

df = pd.DataFrame([lg.text], [attr])
print(df)
df.columns = ["X"]
df.to_excel("hotspot.xlsx", sheet_name="hotspot", index=False)
0
yg_be Messages postés 23228 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 septembre 2024 1 538 > peter76960 Messages postés 11 Date d'inscription vendredi 24 novembre 2023 Statut Membre Dernière intervention 22 juillet 2024
27 nov. 2023 à 22:29

La méthode à appliquer implique de travailler dans la boucle.

0
peter76960 Messages postés 11 Date d'inscription vendredi 24 novembre 2023 Statut Membre Dernière intervention 22 juillet 2024
Modifié le 30 nov. 2023 à 16:33

Dans un premier temps, je cherche à imprimer ma liste de valeur dans excel. Pour instant, je n'y arrive pas, je n'ai toujours qu'une seule valeur,

Je m'occuperais après de les stocker suivant N tuples de 7 éléments.

  1. Quelles sont mes erreurs?
  2. Avez-vous un exemple exercice avec les tuples que je pourrais utiliser pour ma situation sur internet ?

Merci

for lg in tree.findall("//svg:text", ns):
    if "transform" in lg.attrib:
        attr = lg.attrib["transform"]
        '''print(lg.text, attr)'''
        liste_HS = [(lg.text, attr)]
        for HS in liste_HS:
            '''print(HS)'''

        df = pd.DataFrame(liste_HS)
        print(df)
        df.columns = ["A", "B"]
        df.to_excel(
            "hotspot.xlsx",
            sheet_name="hotspot",
            index=False
        )
0
peter76960 Messages postés 11 Date d'inscription vendredi 24 novembre 2023 Statut Membre Dernière intervention 22 juillet 2024
Modifié le 30 nov. 2023 à 16:36

J'ai réussi pour les trois colonnes :

print(liste_HS)
liste_HS1 = [(
    liste_HS[0],
    liste_HS[1][15:22],
    liste_HS[1][24:31]
)]
print(liste_HS1)

df = pd.DataFrame(liste_HS1)
print(df)
df.columns = ["item", "X", "Y"]
df.to_excel(
    "hotspot.xlsx",
    sheet_name='hotspot',
    index=False
)

Résultat :

     0        1        2
0  180  686.714  73.5248
0
peter76960 Messages postés 11 Date d'inscription vendredi 24 novembre 2023 Statut Membre Dernière intervention 22 juillet 2024
4 déc. 2023 à 17:42

Bonjour

Merci mamiemando!! j'ai  juste changé "i = matrix.index("(") + 8"
comme çà je conserve uniquement les 3 valeurs qui m'intéresse

0
mamiemando Messages postés 33284 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 25 septembre 2024 7 787
5 déc. 2023 à 16:02

De rien :-) Pense à basculer ton sujet en résolu la prochaine fois.

Bonne continuation

0