XML::DOM Comment récupérer une donnée? [Résolu] - Perl - Programmation
Marsh Posté le 22-09-2011 à 09:02:48
Merci Gilou !
Tu m'enlèves une épine du pied.
Que signifie le [0] ?
A quoi sert-il?
Encore merci.
Marsh Posté le 22-09-2011 à 10:42:02
@content est un array, comme le @ initial l'indique.
les éléments de cet array sont $content[0], $content[1], ... $content[n] (bon ici, comme le tableau n'a qu'un élément, c'est réduit à $content[0]). Comme les éléments d'un array sont des scalaires, on a un $ devant le nom et non pas un @.
C'est assez déconcertant au départ, quand on apprend le perl, que ça soit pas @content[0], @content[1], ... @content[n] mais $content[0], $content[1], ... $content[n] pour les éléments de l'array, mais on s'y fait.
Noter que dans le prochaine version de Perl, Perl6, dont la release n'a pas de date estimée depuis qques années, mais qui progresse pas mal ces temps ci, on reviendra a la notation intuitive @content[0], @content[1], ... @content[n].
Comme tu as vu, après l'appel à getElementsByTagName ("CompleteName" ), je fais un getFirstChild() sur le premier nœud, parce que le texte est dans un "nœud texte", premier fils du nœud CompleteName.
Ça se voit pas quand le noeud contient que du texte, mais ça se voit quand il a du contenu mixte, comme un
<nœudA>du texte<nœudB>blabla</nœudB>encore du texte</nœudA>
ou nœudA a 3 nœuds fils, un nœud Texte, un nœudB, et un second nœud Texte.
A+,
Marsh Posté le 22-09-2011 à 11:13:24
Encore merci pour tes explications Gilou.
J'essaye maintenant d'aller encore plus loin dans les étapes de vérification.
Il se peut par exemple que l'attribut CompleteName n'existe pas dans l'XML que je vais traiter, et cela je ne le sais pas à l'avance.
Du coup j'essaye d'implémenter un "if exist; alors" je récupère la valeur.
Ceci pour éviter les messages du genre "Can't call method "getFirstChild" on an undefined value"
Voici ce que j'ai fais, mais cela ne fonctionne pas.
Dans tout les cas il m'affiche mon print
Code :
|
Marsh Posté le 22-09-2011 à 11:26:03
C'est bon ce que j'ai fais fonctionne
Cependant je ne sais pas si c'est la bonne méthode ou bien si on peut faire plus court.
Voici le code:
Code :
|
Marsh Posté le 22-09-2011 à 13:20:34
J'ai un autre problème
Dans le fichier source plus bas, j'ai dans différentes "track type" la valeur format.
Selon comment je me place dans le tableau
$tab[0] = je récupère le format de General
$tab[1] = je récupère le format de Video etc...
Avec le code:
Code :
|
Cependant, j'ai des fichiers qui n'ont pas de track type="Audio" streamid="2"
Du coup mon $tab[4] est inconnu car il n'existe pas.
Comment faire pour ne récupérer que le format du track type="Text" par exemple?
Ainsi si je ne récupère que celle là, mon tab aura toujours la valeur $tab[0].
Et avec un "defined" je suis sauvé.
Avez-vous une astuce?
Fichier Source:
Code :
|
Marsh Posté le 22-09-2011 à 13:59:18
Citation : if (defined $tab[0]) |
C'est plus logique de regarder si @tab a des éléments.
if (scalar(@tab))
ou ce qui est équivalent et plus simple,
if (0 + @tab)
l'addition forçant l'interprétation de @tab comme un scalaire qui est évalué comme son nombre d'éléments.
Citation : Comment faire pour ne récupérer que le format du track type="Text" par exemple? |
Comme tu l'as fait pour l'attribut General plus haut
Tu testes la valeur de l'attribut type sur ton element.
my $typeval = $tab[0]->getAttribute("type" );
if ($typeval eq "Text" ) ...
A+,
Marsh Posté le 22-09-2011 à 15:18:38
Merci Gilou,
Malheureusement cela ne fonctionne pas.
Soit la valeur $typeval est vide, soit le tab[] contient toujours l'une des 4 valeurs précédentes (celle de General, Video etc...)
Je ne sais pas où cela coince,
Ci-dessous mon code
Code :
|
Marsh Posté le 22-09-2011 à 21:12:18
Je comprends pas ce que tu cherches à faire.
Quelque chose comme ceci?
Code :
|
A+,
Marsh Posté le 22-09-2011 à 22:10:39
C'est exactement ça Gilou !
Milles merci
J'ai encore du progrès à faire
Marsh Posté le 26-12-2011 à 18:23:22
Bonjour,
J'ai de nouveau un problème pour récupérer une donné à l'intérieur d'un XML avec XML::DOM
J'arrive à récupérer les premiers champs de la balise Content (cf XML ci-dessous)
Code :
|
Cependant je n'arrive pas à récupérer par exemple le champ "Definition" et le champ "fileName" de Media
Je me heurte à des messages d'erreur tel que:
Can't call method "getAttribute" on an undefined value
Can't call method "getFirstChild" on an undefined value
Quelle est la bonne logique là dessus?
Code :
|
Merci d'avance.
Marsh Posté le 27-12-2011 à 13:31:16
Premier cas:
1) tu fais une recherche des éléments de tag EpgElement (a partir de quoi, ça dépend de comment tu veux organiser cela en sortie: ça peut être a partir d'un noeud Content, d'un noeud EpgDescription etc)
2) pour chacun de ces éléments, tu vérifies si il a l'attribut key de valeur la valeur que tu cherches, par exemple définition
3) si oui, tu récupères le contenu du premier fils (le noeud texte) de l'élément
my @Contents = $doc->getElementsByTagName ('Content');
foreach my $Content (@Contents) {
my @EpgElements = $Content->getElementsByTagName ('EpgElement');
foreach my $EpgElement (@EpgElements) {
next if ($EpgElement->getAttribute('key') ne 'Definition');
my $definition = $EpgElement->getFirstChild()->getNodeValue();
................
}
}
Second cas, tu récupères directement la valeur de l'attribut en testant si c'est pas une chaine vide:
my @Medias = $doc->getElementsByTagName ('Media');
foreach my $Media (@Medias) {
my $fname = $Media->getAttribute('fileName');
if ($fname ne "" ) {
............
}
}
A+,
Marsh Posté le 28-12-2011 à 10:27:45
Bonjour,
Merci Gilou c'est parfait.
J'ai une dernière requête, je me heurte à un problème de boucle foreach.
Précédemment tu avais qu'une balise "Content", maintenant j'ai une balise "Content" et une balise "VodItem" qui sont reliées toutes deux par un id commun (Content id= et le ContentRef).
J'essaye simplement de récupérer les données du même film dans ces 2 balises.
Voici l'exemple de 2 films:
Code :
|
Ici, je veux récupérer:
- le content id
- le titre du film
- la définition du film
- le nom de sa jaquette
- le voditem contentRef (qui est identique au content id)
- le voditem id
- la date de fin
Pour me donner en résultat final cet écran:
Code :
|
Hors, quand je rajoute le tableau @Periods j'obtiens:
Code :
|
C'est le fait de faire un foreach sur la @Periods qui je pense ne vas pas car il me donne chacun des dates de chacun des films alors qu'une seule est la bonne.
Pourtant je vérifie que je suis dans le "bon" @VodItems avec mon "if" mais cela n'a pas l'air de fonctionner.
Bref je ne suis pas sûr d'être clair car c'est assez difficile à expliquer, ce que je souhaite c'est de récupérer la bonne date du bon film tout en gardant les précédent champ.
Ci-dessous mon code.
Code :
|
Marsh Posté le 28-12-2011 à 12:35:38
Déjà une chose:
Quand tu veux ça
Citation : Ici, je veux récupérer: |
par record, il faut créer un hash perl pour stocker les valeurs, avec l'id comme clef, ça saute aux yeux.
J'ai la crève, alors je tacherai de te repondre cet aprem.
A+,
Marsh Posté le 28-12-2011 à 14:15:51
Tiens, voici comment faire en passant par un hash (ou plutôt un hash de hash en fait)
Code :
|
C:\Perl>perl VOD.pl |
Bon, c'est a améliorer en tenant compte des tests a effectuer si les attributs id ou contentRef sont absents, ou que @Periods n'est pas vide.
Ca suppose que pour un content donné, il n'y a qu'un seul VodItem tels que le contentRef du VodItem = le id du Content, sinon ça ne marchera pas et il faudra faire une variante un tout petit peu plus compliquée avec un hash pour les Contents et un pour les VodItems.
A+,
Marsh Posté le 28-12-2011 à 14:40:11
Merci Gilou !
Je vais tester cela de ce pas
Cependant je vois que dans ton résultat la date est identique alors qu'on devrait avoir une au 30/11 et l'autre au 31/12
Marsh Posté le 28-12-2011 à 14:44:26
Oui, je venais justement de voir ça dans mes tests.
C'estr un copier coller un peu trop hatif.
Remplacer
my @Periods = $doc->getElementsByTagName ('Period');
par
my @Periods = $VodItem->getElementsByTagName ('Period');
A+,
Marsh Posté le 28-12-2011 à 14:47:04
Bon, sinon, si tu peux avoir plusieurs VodItems referençant un même Content, il faudrait un code du style suivant:
Code :
|
A+,
Marsh Posté le 28-12-2011 à 15:45:43
Grand merci pour ton aide Gilou !
Je vais m'atteler à examiner tout cela.
Marsh Posté le 29-12-2011 à 18:09:09
Cela fonctionne à la perfection.
Encore merci pour m'avoir débloqué.
Marsh Posté le 22-09-2011 à 00:17:09
Bonjour,
Voici mon fichier source:
Ici mon script:
J'arrive a récupérer la track "General"
Mais je n'arrive pas à récupérer par exemple le nom de fichier Files_Encoded.ts appartenant au tag CompleteName
Comment faire?
Merci d'avance.
Message édité par Sethenssen le 22-09-2011 à 10:18:22