Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 30/06/2013, à 19:22

Pierrouf

[Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Bonjour à tous,
je suis le newb ultime du script (je me suis contenté pour l'instant de modifier des scripts existants), et du coup ma demande va vous paraître simple.
J'ai un .xml (fichier edl de cinelerra), dont je souhaite modifier des paramètres (pour permettre de travailler sur fichiers proxy).
Le fichier typique contient:

<CAMERA_Z>
<AUTO POSITION="0" VALUE="1" CONTROL_IN_VALUE="0" CONTROL_OUT_VALUE="0" TANGENT_MODE="0"></AUTO>
</CAMERA_Z>
<PROJECTOR_X>
<AUTO POSITION="0" VALUE="0" CONTROL_IN_VALUE="0" CONTROL_OUT_VALUE="0" TANGENT_MODE="0"></AUTO>
<AUTO POSITION="1193" VALUE="0" CONTROL_IN_VALUE="0" CONTROL_OUT_VALUE="0" TANGENT_MODE="0"></AUTO>
<AUTO POSITION="1248" VALUE="-6.936000e+02" CONTROL_IN_VALUE="0" CONTROL_OUT_VALUE="0" TANGENT_MODE="0"></AUTO>
<AUTO POSITION="1432" VALUE="-5.376000e+02" CONTROL_IN_VALUE="0" CONTROL_OUT_VALUE="0" TANGENT_MODE="0"></AUTO>
</PROJECTOR_X>
<PROJECTOR_Y>
<AUTO POSITION="0" VALUE="0" CONTROL_IN_VALUE="0" CONTROL_OUT_VALUE="0" TANGENT_MODE="0"></AUTO>
<AUTO POSITION="1193" VALUE="0" CONTROL_IN_VALUE="0" CONTROL_OUT_VALUE="0" TANGENT_MODE="0"></AUTO>
<AUTO POSITION="1248" VALUE="-3.024000e+02" CONTROL_IN_VALUE="0" CONTROL_OUT_VALUE="0" TANGENT_MODE="0"></AUTO>
</PROJECTOR_Y>

Pour commencer mon but est de multiplier par une constante, les valeurs VALUE qui sont entre les balises <PROJECTOR_X> et </PROJECTOR_X>. Une fois que je saurai faire ça, je devrais pouvoir me débrouiller pour les autres modifs.

Pour ce faire, j'avais trouvé un programme en python qui ne semble pas marcher malgré quelques heures de bidouille.
Je me suis ensuite interessé au regex, mais j'ai l'impression que c'est vraiment trop geek pour moi (mais je trouve ça très beau!). Awk est du même acabit...
Du coup j'imagine qu'un script devrait faire l'affaire, mais en fait je ne sais pas trop par où commencer.
En fait ce qui me bloque le plus c'est que:
- l'endroit à modifier n'est pas sur la même ligne que la balise à repérer (je voulais utiliser sed ou/et grep).
- il faut récupérer la valeur, la multiplier puis la remettre à sa place

Bref, un petit pas pour un master du script, un trop grand pas pour un newb comme moi!

Merci

Dernière modification par Pierrouf (Le 08/07/2013, à 03:14)

Hors ligne

#2 Le 30/06/2013, à 20:23

nesthib

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Un exemple en awk pour faire l'opération 3⋅x+1 sur VALEUR="x" :

awk '/<PROJECTOR_X>/,/<\/PROJECTOR_X>/{match($0, / VALUE="([^"]*)"/, NUM) ; gsub(/ VALUE="([^"]*)"/, " VALUE=\""(3*NUM[1]+1)"\"", $0)} 1'

On travaille entre les balises projector.
On récupère (match) la valeur numérique.
On la remplace (gsub) dans la ligne ($0) par sa valeur modifiée.

Autre solution, tu peux utiliser le module xml de python, trouver tes branches selon les parents et modifier la valeur.


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#3 Le 30/06/2013, à 20:58

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Merci!
j'ai essayé ton code, mais cela me renvoie une erreur:

$ awk '/<PROJECTOR_X>/,/<\/PROJECTOR_X>/{match($0, / VALUE="([^"]*)"/, NUM) ; gsub(/ VALUE="([^"]*)"/, " VALUE=\""(3*NUM[1]+1)"\"", $0)} 1' proxy20.xml
awk: line 1: syntax error at or near ,

Déjà je ne sais pas de quelle virgule il parle.
Dans les docs match semble s'attendre à seulement 2 arguments, et ne renvoyer que la position de l'occurence de "VALUE=". En même temps j'avoue avoir du mal à comprendre ton code...

Hors ligne

#4 Le 30/06/2013, à 21:21

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

en fait j'ai bidouillé et je crois que je tiens le bon bout:


awk '/<PROJECTOR_X>/,/<\/PROJECTOR_X>/{match($0, / VALUE="([^"]*)" NUM/) ; gsub(/ VALUE="([^"]*)"/, " VALUE=\""(3*NUM[1]+1)"\"", $0)} 1' proxy20.xml

il faudrait juste que je trouve comment faire pour qu'il modifie bien mon fichier...

Hors ligne

#5 Le 30/06/2013, à 21:28

pingouinux

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Bonsoir,
Voici une solution en python, nettement moins concise que celle de nesthib.

#! /usr/bin/python
# -*- coding: utf-8 -*-

import sys, re

fic,cst=sys.argv[1:3]
cst=float(cst)

with open(fic,'r') as f :
   fin=f.read()

rec_projx=re.compile('\B(.*?)(<PROJECTOR_X>.*?</PROJECTOR_X>)(.*)\Z',re.S)
rec_val=re.compile('\sVALUE="([\d.eE+-]+)"\s')

with open(fic+'.modifie','w') as g :
   k1=rec_projx.search(fin)
   while k1 :
      deb,projx,fin=k1.groups()[:3]

      g.write(deb)
      k2=rec_val.search(projx)
      while k2 :
         val=float(k2.group(1))*cst
         g.write(projx[:k2.start(1)])
         g.write("%s"%val)
         projx=projx[k2.end(1):]
         k2=rec_val.search(projx)
      g.write(projx)

      k1=rec_projx.search(fin)

   g.write(fin)

Usage :

./script_python fichier constante_multiplicative

Ce script génère le fichier fichier.modifie

Hors ligne

#6 Le 30/06/2013, à 21:39

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

merci Pingouinux.
Il va falloir que j'analyse ton code (par ce problème je suis déjà en train de découvrir regexe et awk, pourquoi pas le python aussi!)
Entre temps j'ai persisté sur la soluce de nesthib:

exec 3<proxy20.xml
rm -f proxy20.xml
cat 0<&3 | awk '/<PROJECTOR_X>/,/<\/PROJECTOR_X>/{match($0, / VALUE="([^"]*)" NUM/) ; gsub(/ VALUE="([^"]*)"/, " VALUE=\""(3*NUM[1]+1)"\"", $0)} 1' > proxy20.xml

on dirait que cela marche.

De manière générale, pour bidouiller comme ça vous conseillez quoi? Script bash, python, autre?

En tout cas grand merci (je passe en résolu dès que je suis sur que cela marche).

Hors ligne

#7 Le 30/06/2013, à 21:42

nesthib

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

@Pierrouf : awk ne modifie pas les fichier en place, il faut que tu rediriges la sortie vers un fichier temporaire et que tu remplaces ton ancien fichier :

awk… fichier >fichier.tmp
mv fichier.tmp fichier

N'essaie pas d'utiliser le même fichier en entrée et sortie, ça ne fonctionnerait pas wink

edit : ta solution de jouer avec les descripteurs de fichier et de faire le rm -rf est mauvaise. S'il y a le moindre problème tu perdras ton fichier.

@pingouinux : quitte à utiliser python, autant utiliser des modules qui lisent le xml wink

Dernière modification par nesthib (Le 30/06/2013, à 21:44)


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#8 Le 30/06/2013, à 21:55

pingouinux

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

@Pierrouf #6 : Je n'aurais pas osé utiliser un truc pareil, et le pire est que ça a l'air de marcher… nesthib a raison, la moindre erreur risque d'écraser ton fichier d'origine. Personnellement, je ferais même un diff entre les deux fichiers avant le mv.

nesthib   #7 a écrit :

quitte à utiliser python, autant utiliser des modules qui lisent le xml

Il faudra que je regarde ça un de ces jours. J'ai utilisé ici une méthode que je connais bien.

Hors ligne

#9 Le 30/06/2013, à 21:55

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Ok chef!
j'ai une excuse: c'est pas mon idée! (bien trop compliqué pour moi).
(et puis je travaille sur des copies bien sur...)
Par contre, le NUM ne marche pas. Il remplace systématiquement la valeur par 1 (comme si NUM[1] restait égal à 0).
Comme j'ai bidouillé autour du NUM du match, j'ai du faire une c***nerie...

[edit]
@Pingouinux
j'ai essayé ton script, et j'ai l'impression qu'il ne change rien au fichier destination (.modifie)

Dernière modification par Pierrouf (Le 30/06/2013, à 22:14)

Hors ligne

#10 Le 30/06/2013, à 22:36

pingouinux

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Pourtant, je l'ai testé. Tu n'as pas donné une constante multiplicative égale à 1, par hasard ? Ou alors, ton fichier de départ n'est pas structuré comme celui que tu donnes en #1.

Hors ligne

#11 Le 30/06/2013, à 22:56

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

OK j'ai trouvé. L'extrait de fichier sur lequel j'ai testé, avait une structure très légèrement différente (car extrait à un autre endroit):

<CAMERA_X>
<AUTO CONTROL_IN_VALUE="2" CONTROL_OUT_VALUE="0" POSITION="0" TANGENT_MODE="0" VALUE="2"></AUTO>
</CAMERA_X>

du coup j'imagine que le pb c'est que la les guillemets sont suivis de > au lieu d'une espace.
J'ai essayé sur la variable AUTO CONTROL_IN_VALUE, et là ça marche.
Du coup j'imagine que "\s" ne peut pas représenter le ">". T'as une astuce? (sinon je peux être bourrin et traiter par des rechercher/remplacer le fichier avant de le passer à ta moulinette)

Dernière modification par Pierrouf (Le 30/06/2013, à 22:56)

Hors ligne

#12 Le 30/06/2013, à 23:11

pingouinux

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Dans ce cas, remplace cette ligne

rec_val=re.compile('\sVALUE="([\d.eE+-]+)"\s')

par celle-ci

rec_val=re.compile('\\bVALUE="([\d.eE+-]+)"')

Hors ligne

#13 Le 30/06/2013, à 23:33

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Merci encore!
Comme il faudra que je fasse plusieurs opérations, je suis en train de décrypter ton code pour pouvoir le modifier.
Je le commente comme je peux (j'ai commencé le python il y a 10 minutes...), et je le publie pour que tu me dises si j'ai bien compris.

Hors ligne

#14 Le 01/07/2013, à 00:42

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Re,
voici comment je comprends ton code:

#! /usr/bin/python
# -*- coding: utf-8 -*-

import sys, re			

fic,cst=sys.argv[1:3]		# enregistre dans fic le fichier source et cst la constante multiplicative: pourquoi 1:3???
cst=float(cst)			# transforme l'argument cst en un float

with open(fic,'r') as f :	# ouvre le fichier source en read only dans l'objet f
   fin=f.read()			# met le fichier dans une chaine de caractère appelée fin

rec_projx=re.compile('\B(.*?)(<CAMERA_X>.*?</CAMERA_X>)(.*)\Z',re.S)	# crée un pattern de recherche pour ce qui est entre les balises <camera_x et /camera_x (regex à décrypter)
rec_val=re.compile('\sCONTROL_IN_VALUE="([\d.eE+-]+)"\s')		# crée un pattern de recherche pour ce qui est entre guillements après l'expression " CONTROL_IN_VALUE=" et avant le guillement qui suit (ainsi que l'espace) (regex à décrypter)

with open(fic+'.modifie','w') as g :		#crée (en écriture) un fichier avec l'extension.modifie, connu sous g dans le script
   k1=rec_projx.search(fin)			# crée un l'objet de recherche du pattern de balise projx dans fin
   while k1 :					# le résultat de k1 est un booléen: tant que les balises sont trouvées execute ce qui suit
      deb,projx,fin=k1.groups()[:3]		# sépare les sections délimitées par le pattern détecté par rec_projx en 3 variables: ce qui est avant le pattern: deb, le pattern: projx, ce qui est après le pattern: fin

      g.write(deb)				# enregistre dans g la portion avant le pattern
      k2=rec_val.search(projx)			# crée l'objet de recherche de l'expression définie dans rec_val (qui cherche dans le pattern)
      while k2 :				# booléen du résultat de la recherche (ya intérêt qu'il prenne au moins une fois la valeur 1, sinon il faudrait le signaler, voire créer la valeur...
         val=float(k2.group(1))*cst		# crée la valeur modifiée, en multipliant la 2ème section trouvée par rec_val.search par la constante
         g.write(projx[:k2.start(1)])		# écrit dans le fichier cible g le contenu de projx jusqu'à l'endroit où il a reconnu l'expression reconnue par rec_val.search
         g.write("%s"%val)			# écrit la variable modifiée
         projx=projx[k2.end(1):]		# écrit le contenu de ce qui suit l'expression reconnue dans projx
         k2=rec_val.search(projx)		# refait une recherche de la l'expression rec_val dans projx (et du coup réarme k2 pour while k2)
      g.write(projx)				# comme la boucle précédente s'arrète sur un k2=0 cela veut dire qu'il n'a pas trouvé la séquence. Il écrit dans le fichier cible la section entre l'expression reconnue pour la dernière fois et la balise de fin

      k1=rec_projx.search(fin)			#réarme k1 pour en recherchant le jeu de balises suivant

   g.write(fin)					#écrit la section du fichier se trouvant entre la dernière balise et la fin du fichier

C'est marrant le python, ça doit t'apprendre où se trouve le point (vu que cela semble le pivot de sa grammaire) et à indenter correctement (pas de fin de boucle!)

Mon prochain défit:
- comprendre parfaitement le regex (si cela en est) que tu as mis
- faire du remplacement d'extension de fichier (ça devrait le faire si j'ai compris le regex)
- gérer mes résolutions (basculer toutes les résolutions des fichiers sources et cibles)

Hors ligne

#15 Le 01/07/2013, à 01:21

nesthib

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Une façon propre (:P) en python. Nécessite le module python lxml.

#!/usr/bin/python
# coding: utf-8
import lxml.etree

with open('/tmp/cinelerra.xml', 'r') as f:
    doc = lxml.etree.fromstring(f.read())    # on lit le fichier xml d'origine

objets = doc.xpath('//PROJECTOR_X/*[@VALUE]')    # on cherche les balises ayant un attribut VALUE et appartenant au parent PROJECTOR_X

for objet in objets:
    try:
        valeur = float(objet.get('VALUE'))    # on récupère la valeur de l'attribut VALUE
        objet.set('VALUE', '%s' % (3*valeur+1))    # et on la remplace par 3*valeur+1
    except ValueError:
        print("attention, valeur non numérique")

with open('/tmp/cinelerra.2.xml', 'w') as f:
    f.write(lxml.etree.tostring(doc))    # on enregistre le fichier

NB. Attention, comme c'est du XML, les balises sont sensibles à la casse !


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#16 Le 01/07/2013, à 03:07

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Génial ça marche!

Dès que j'ai tout compris, et que je sais manipuler les chaînes de caractères (pour modifier les noms de fichier) j'applique en grandeur nature pour voir comment ça le fait.

Tu sais comment mettre un warning si il n'y a pas d'attribut value dans une balise?
Et rajouter l'attribut value si il n'existe pas ? (je sais pas encore si c'est nécessaire)

Tant qu'à t'embêter, une dernière question. Sais tu comment je peux pointer vers les valeurs (qui n'ont pas de nom) dans les balises POINT qui sont elles mêmes dans les balises MASK qui semblent elles-mêmes être dans une balise MASKAUTOS:

<MASKAUTOS>
<AUTO MODE="0" VALUE="100" FEATHER="50" APPLY_BEFORE_PLUGINS="0" POSITION="0">
<MASK NUMBER="0">

<POINT>969.221, 7.094788, 0, 0, 225.4588, -3.153198</POINT>
<POINT>995, 12, 0, 0, 0, 0</POINT>
<POINT>1401.219, 560.4931, -17.3429, -309.0201, -40.99268, 346.8593</POINT>
<POINT>999.1774, 1068.169, 282.2174, 1.576537, -277.4874, -18.91955</POINT>
<POINT>527.7637, 634.5948, 31.53259, 157.6633, 17.34296, -184.4661</POINT>
<POINT>552.3287, 445.6098, 0, 0, 0, 0</POINT>
<POINT>969.221, 7.094788, -424.1143, 93.02135, 0, 0</POINT>
</MASK>

</AUTO>
<AUTO MODE="0" VALUE="100" FEATHER="50" APPLY_BEFORE_PLUGINS="0" POSITION="0">
<MASK NUMBER="0">

<POINT>1125.221, -120.9052, 0, 0, 225.4588, -3.153198</POINT>
<POINT>1467, -104, 0, 0, 0, 0</POINT>
<POINT>2201.219, 48.4931, -17.3429, -309.0201, -40.99268, 346.8593</POINT>
<POINT>1995.177, 1156.169, 282.2174, 1.576537, -277.4874, -18.91955</POINT>
<POINT>-128.2363, 1206.595, 31.53259, 157.6633, 17.34296, -184.4661</POINT>
<POINT>-231.6713, -74.3902, 0, 0, 0, 0</POINT>
<POINT>985.221, -116.9052, -424.1143, 93.02135, 0, 0</POINT>
</MASK>

</AUTO>
<AUTO MODE="0" VALUE="100" FEATHER="50" APPLY_BEFORE_PLUGINS="0" POSITION="1157">
<MASK NUMBER="0">

<POINT>1125.221, -120.9052, 0, 0, 225.4588, -3.153198</POINT>
<POINT>1467, -104, 0, 0, 0, 0</POINT>
<POINT>2201.219, 48.4931, -17.3429, -309.0201, -40.99268, 346.8593</POINT>
<POINT>1995.177, 1156.169, 282.2174, 1.576537, -277.4874, -18.91955</POINT>
<POINT>-128.2363, 1206.595, 31.53259, 157.6633, 17.34296, -184.4661</POINT>
<POINT>-231.6713, -74.3902, 0, 0, 0, 0</POINT>
<POINT>985.221, -116.9052, -424.1143, 93.02135, 0, 0</POINT>
</MASK>

</AUTO>
<AUTO MODE="0" VALUE="100" FEATHER="50" APPLY_BEFORE_PLUGINS="0" POSITION="1169">
<MASK NUMBER="0">

<POINT>969.221, 7.094788, 0, 0, 225.4588, -3.153198</POINT>
<POINT>995, 12, 0, 0, 0, 0</POINT>
<POINT>1401.219, 560.4931, -17.3429, -309.0201, -40.99268, 346.8593</POINT>
<POINT>999.1774, 1068.169, 282.2174, 1.576537, -277.4874, -18.91955</POINT>
<POINT>527.7637, 634.5948, 31.53259, 157.6633, 17.34296, -184.4661</POINT>
<POINT>552.3287, 445.6098, 0, 0, 0, 0</POINT>
<POINT>969.221, 7.094788, -419.7307, 93.02135, 0, 0</POINT>
</MASK>

</AUTO>
</MASKAUTOS>

J'en demande pas plus, sinon tu vas tout me faire!

merci beaucoup.

Hors ligne

#17 Le 01/07/2013, à 03:47

nesthib

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Pierrouf a écrit :

Tu sais comment mettre un warning si il n'y a pas d'attribut value dans une balise?

une fois que tu as défini l'objet sur lequel tu travailles (avec une recherche xpath par exemple) :

if not 'VALUE' in objet.keys():
    print('attention, VALUE n'existe pas')

ou, pour considérer les attributs vides ("") comme inexistants :

if not objet.get('VALUE'):
    print('attention, VALUE n'existe pas ou est vide')
Pierrouf a écrit :

Et rajouter l'attribut value si il n'existe pas ? (je sais pas encore si c'est nécessaire)

objet.set('VALUE', 'valeur')
Pierrouf a écrit :

Tant qu'à t'embêter, une dernière question. Sais tu comment je peux pointer vers les valeurs (qui n'ont pas de nom) dans les balises POINT qui sont elles mêmes dans les balises MASK qui semblent elles-mêmes être dans une balise MASKAUTOS:

pour avoir la ligne de texte :

for point in doc.xpath('/MASKAUTOS//POINT'):
    print(point.text)

Pour récupérer une liste de valeurs :

for point in doc.xpath('/MASKAUTOS//POINT'):
    print([float(i) for i in point.text.split(', ')])
Pierrouf a écrit :

J'en demande pas plus, sinon tu vas tout me faire!
merci beaucoup.

Je t'en prie.


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#18 Le 01/07/2013, à 04:47

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Avec ça j'ai du grain à moudre!
A moi la puissance de cinelerra en proxy! (déjà que je l'ai mis en grappe de calcul...)
Sinon ça a l'air sympa le python.
Moi qui voulais me lancer dans un langage, je me demande si je vais pas partir sur du python...

Merci encore à vous 2, et j'espère qu'un jour je pourrai m’acquitter de ma dette!

Dernière modification par Pierrouf (Le 01/07/2013, à 04:49)

Hors ligne

#19 Le 01/07/2013, à 05:15

nesthib

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Comme tu peux le voir python est à la fois puissant et extrêmement lisible. C'est un excellent langage pour apprendre… mais aussi pour travailler.

N'hésite pas à demander si tu as des questions.


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#20 Le 01/07/2013, à 07:16

pingouinux

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Pierrouf   #14 a écrit :

fic,cst=sys.argv[1:3]        # enregistre dans fic le fichier source et cst la constante multiplicative: pourquoi 1:3???

sys.argv est une liste contenant le nom du script (tel qu'il est appelé), et la liste des paramètres.
sys.argv[n1:n2] est une section de cette liste (slice), comprenant tous les éléments de n1 (inclus) à n2 (exclu). Les indices commencent à zéro.

Pour le reste, tu as bien compris ce que faisait mon script.

@nesthib : Ton exemple avec lxml m'a convaicu. Merci

Hors ligne

#21 Le 01/07/2013, à 07:29

nesthib

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

de rien wink


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#22 Le 04/07/2013, à 05:59

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

En fait j'ai encore un pb!
Le script (de nesthib) marchait bien sur un xml simple (mais bien issu de cinelerra).
Mais maintenant j'ai pris un cas réel (un vidéo que j'avais faite auparavant), et là ça marche plus!
Il me dit:

Traceback (most recent call last):
  File "./script_python_3", line 6, in <module>
    doc = lxml.etree.fromstring(f.read())    # on lit le fichier xml d'origine
  File "lxml.etree.pyx", line 2756, in lxml.etree.fromstring (src/lxml/lxml.etree.c:54726)
  File "parser.pxi", line 1578, in lxml.etree._parseMemoryDocument (src/lxml/lxml.etree.c:82843)
  File "parser.pxi", line 1457, in lxml.etree._parseDoc (src/lxml/lxml.etree.c:81641)
  File "parser.pxi", line 965, in lxml.etree._BaseParser._parseDoc (src/lxml/lxml.etree.c:78311)
  File "parser.pxi", line 569, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:74567)
  File "parser.pxi", line 650, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:75458)
  File "parser.pxi", line 590, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:74791)
lxml.etree.XMLSyntaxError: expected '>', line 8084, column 3

Il ne crée pas le nouveau fichier.

Ci-dessous les lignes 8078 à 8084 du fichier source:

<POINTS>
<POINT X="5.725076e-01" Y="5.687638e-01">
<POINT X="6.857143e-01" Y="8.375000e-01">
<POINT X="6.969298e-01" Y="7.246698e-01">
<POINT X="7.314286e-01" Y="7.916667e-01">
<POINT X="7.514285e-01" Y="7.250000e-01">
</POINTS>

J'ai fini par comprendre que c'est le formatage des balises qui lui plaît pas.
Quand je rajoute un / avant le > pour la série de POINT, il me change la ligne d'erreur...
Je me suis fait tout le fichier, et finalement ça passe.
Mais, c'est quand même assez lourd.
Question: Comment faire pour nettoyer le fichier?

Bon ensuite, maintenant que lxml était content, j'ai vérifié que la modif ne perturbait pas Cinelerra: OK.

Je passe ensuite la moulinette (donc le script python).
=> ça plante dans Cinelerra
Quand je compare avant et après, je remarque que des lignes ont disparu.
La chaîne:
\n Cr\\E9\\E9 depui\\A0:\n
était remplacée par:
  Cr\\E9\\E9 depui\\A0:
Donc en gros de temps en temps 2 lignes étaient supprimées.
J'ai donc corrigé tout ça (remplacement dans gedit), et là encore bug...
Il semblerait que des balises de fin soient modifiées:

<PANAUTOS>
<AUTO POSITION="0" HANDLE_X="1" HANDLE_Y="50" VALUE0="1" VALUE1="0"></AUTO><AUTO POSITION="2314312" HANDLE_X="51" HANDLE_Y="51" VALUE0="1" VALUE1="1"></AUTO></PANAUTOS>

remplacé par

<PANAUTOS>
<AUTO POSITION="0" HANDLE_X="1" HANDLE_Y="50" VALUE0="1" VALUE1="0"/><AUTO POSITION="2314312" HANDLE_X="51" HANDLE_Y="51" VALUE0="1" VALUE1="1"/></PANAUTOS>

En fait de manière générale il me remplace les:

></BALISE_FIN>

par

/>

Help!

Hors ligne

#23 Le 04/07/2013, à 07:05

nesthib

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

lxml nécessite des fichiers xml valides pour fonctionner. En xml, une balise ouverte doit être fermée (une balise ouvrante seule est invalide).
<x></x> est syntaxiquement équivalent à <x /> lorsqu'il n'y a pas de valeur dans la balise.

Il semble donc que le soucis soit dû à cinelera qui ne gère pas correctement le xml.


GUL Bordeaux : GirollServices libres : TdCT.org
Hide in your shell, scripts & astuces :  applications dans un tunnelsmart wgettrouver des pdfinstall. auto de paquetssauvegarde auto♥ awk
  ⃛ɹǝsn xnuᴉꞁ uʍop-ǝpᴉsdn

Hors ligne

#24 Le 04/07/2013, à 14:47

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

En fait, en dehors des <POINT> (à traiter séparément), je pense que Cinelerra génère des fichiers xml valides, de type <x></x>.
Mais lxml les transforme en <x /> dans certains cas, ce que Cinelerra ne supporte pas.
Donc la question devient, comment forcer lxml à conserver la syntaxe <x></x>?

Hors ligne

#25 Le 08/07/2013, à 03:12

Pierrouf

Re : [Résolu] multiplier des paramètres balisés dans xml (pour Cinelerra)

Après avoir travaillé jour et nuit sur ce f*** script, j'ai fini par y arriver!
Bilan: j'ai dû adopter la méthode Pingouinux pour nettoyer le fichier et le rendre lisible par lxml, puis la méthode Nesthib pour modifier les attributs de balises (et il y en a un paquet...) et enfin à nouveau la méthode Pingouinux pour "denettoyer" le fichier et le rendre lisible par Cinelerra.
A noter que j'avais commencé à tout faire en méthode Pingouinux, mais cela a commencé à devenir très compliqué (il aurait fallu être ceinture noire de regex), et également à ralentir sérieusement (nombreuses boucles d'écriture sur un fichier de 500 ko)

Il faudra que je vérifie si le script est robuste à tout les schémas de montage (dans Cinelerra).
Il faudrait probablement que je le nettoie pour le rendre lisible et un peu plus élégant.
En tous cas un grand merci à vous 2.
Je passe en résolu, et j'espère pouvoir un jour partager ce script avec d'autres...

Hors ligne