Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1623 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  [Résolu] XML::DOM Comment récupérer une donnée?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Résolu] XML::DOM Comment récupérer une donnée?

n°2102772
Sethenssen
Posté le 22-09-2011 à 00:17:09  profilanswer
 

Bonjour,
 
Voici mon fichier source:

Code :
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <File>
  3. <track type="General">
  4. <ID_String>0 (0x0)</ID_String>
  5. <CompleteName>Files_Encoded.ts</CompleteName>
  6. <Format>MPEG-TS</Format>
  7. <FileSize_String>594 MiB</FileSize_String>
  8. </track></File>


 
Ici mon script:

Code :
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use XML::DOM;
  5. #************************************************************
  6. # GlobalVariables
  7. my $OUTFILE;
  8. my $OUTDIR;
  9. my $parser;
  10. my $doc;
  11. my @content;
  12. my $element;
  13. my $TFILE;
  14. my $id_cont;
  15. #************************************************************
  16. # Script Starting...
  17. $OUTDIR = "/cygdrive/d/_.compil/";
  18. $OUTFILE = "Test.xml";
  19. $parser = new XML::DOM::Parser();
  20. $doc = $parser->parsefile ($OUTFILE);
  21. print "$OUTDIR"."$OUTFILE"."\n\n";
  22. @content = $doc->getElementsByTagName ("track" );
  23. foreach $element (@content)
  24. {
  25.  $id_cont = $element->getAttribute ("type" );
  26.  $TFILE = $element->toString();
  27.  print $id_cont . "\n";
  28. }
  29. $doc->dispose;
  30. __END__


 
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
mood
Publicité
Posté le 22-09-2011 à 00:17:09  profilanswer
 

n°2102777
gilou
Modérateur
Modzilla
Posté le 22-09-2011 à 02:26:55  profilanswer
 

Code :
  1. @content = $doc->getElementsByTagName ("CompleteName" );
  2. print $content[0]->getFirstChild()->toString();


A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2102799
Sethenssen
Posté le 22-09-2011 à 09:02:48  profilanswer
 

Merci Gilou !
Tu m'enlèves une épine du pied.
 
Que signifie le [0] ?
A quoi sert-il?
 
Encore merci.

n°2102818
gilou
Modérateur
Modzilla
Posté le 22-09-2011 à 10:42:02  profilanswer
 

@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+,


Message édité par gilou le 22-09-2011 à 10:49:31

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2102820
Sethenssen
Posté le 22-09-2011 à 11:13:24  profilanswer
 

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 :
  1. if (defined $doc->getElementsByTagName ("CompleteName" ) )
  2. {
  3.  @tab = $doc->getElementsByTagName ("CompleteName" );
  4.  $CompleteName = $tab[0]->getFirstChild()->toString();
  5.  print "$CompleteName\n";               
  6. }

n°2102823
Sethenssen
Posté le 22-09-2011 à 11:26:03  profilanswer
 

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 :
  1. foreach $element (@track)
  2. {
  3.  $_ = $ligne;
  4.  $type = $element->getAttribute ("type" );
  5.  $ligne = $element->toString();
  6.  if($type eq "General" )
  7.   {
  8.    $chk=1;
  9.    @tab = $doc->getElementsByTagName ("CompleteName" );
  10.    if (defined $tab[0])
  11.     {
  12.      print "OK\n";
  13.      $CompleteName = $tab[0]->getFirstChild()->toString();
  14.      @tab = split/\\/,$CompleteName;
  15.      $CompleteName = $tab[2];
  16.      print "$CompleteName\n";
  17.     }
  18.      else
  19.       {
  20.        print "KO\n";
  21.        $CompleteName="";
  22.       }
  23.   }
  24. }


Message édité par Sethenssen le 22-09-2011 à 11:27:10
n°2102840
Sethenssen
Posté le 22-09-2011 à 13:20:34  profilanswer
 

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 :
  1. @tab = $doc->getElementsByTagName ("Format" );
  2. $format = $tab[0]->getFirstChild()->toString();
  3. print "$format\n";


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 :
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Encoded>
  3. <File>
  4. <track type="General">
  5. <CompleteName>Video01.ts</CompleteName>
  6. <Format>MPEG-TS</Format>
  7. </track>
  8. <track type="Video">
  9. <Format>MPEG Video</Format>
  10. </track>
  11. <track type="Audio" streamid="1">
  12. <Format>MPEG Audio</Format>
  13. </track>
  14. <track type="Audio" streamid="2">
  15. <Format>MPEG Audio</Format>
  16. </track>
  17. <track type="Text">
  18. <Format>Ceefax</Format>
  19. </track>
  20. </File>
  21. </Encoded>


Message édité par Sethenssen le 22-09-2011 à 13:21:43
n°2102846
gilou
Modérateur
Modzilla
Posté le 22-09-2011 à 13:59:18  profilanswer
 

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+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2102862
Sethenssen
Posté le 22-09-2011 à 15:18:38  profilanswer
 

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 :
  1. @track = $doc->getElementsByTagName ("track" );
  2. foreach $element (@track)
  3. {
  4.  $_ = $ligne;
  5.  $type = $element->getAttribute ("type" );
  6.  if($type eq "General" )
  7.   {
  8.    $chk=1;
  9.    @tab = $doc->getElementsByTagName ("FileName" );
  10.    if (0+@tab)
  11.     {
  12.      print "OK\n";
  13.      $CompleteName = $tab[0]->getFirstChild()->toString();
  14.      @tab = split/\\/,$CompleteName;
  15.      $CompleteName = $tab[0];
  16.      print "$CompleteName\n";
  17.     } else {
  18.        print "KO\n";
  19.        $CompleteName="";
  20.         }
  21.   }
  22.  if($type eq "Text" )
  23.   {
  24.    $chk=5;
  25.    @tab = $doc->getElementsByTagName ("Format" );
  26.    $Text_Codec = $tab[0]->getFirstChild()->toString();
  27.    @tab = $doc->getElementsByTagName ("Format" );
  28.    my $typeval = $tab[0]->getAttribute("type" );
  29.    print "$typeval\n";
  30.    $format = $tab[1]->getFirstChild()->toString();
  31.    print "$format\n";
  32.  }
  33. }


Message édité par Sethenssen le 22-09-2011 à 15:19:48
n°2102930
gilou
Modérateur
Modzilla
Posté le 22-09-2011 à 21:12:18  profilanswer
 

Je comprends pas ce que tu cherches à faire.
Quelque chose comme ceci?
 

Code :
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5. use XML::DOM;
  6.  
  7. my $parser = new XML::DOM::Parser();
  8. my $doc = $parser->parsefile('Test.xml');
  9. my @tracks = $doc->getElementsByTagName('track');
  10. foreach my $track (@tracks) {
  11.  my $type = $track->getAttribute('type');
  12.  if ($type eq "Text" ) {
  13.    my @format = $track->getElementsByTagName('Format');
  14.    if (0 + @format) {
  15.      print $format[0]->getFirstChild()->toString();
  16.    }
  17.  }
  18. }
  19. $doc->dispose;


 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
mood
Publicité
Posté le 22-09-2011 à 21:12:18  profilanswer
 

n°2102941
Sethenssen
Posté le 22-09-2011 à 22:10:39  profilanswer
 

C'est exactement ça Gilou !
 
Milles merci
 
J'ai encore du progrès à faire :)

n°2118364
Sethenssen
Posté le 26-12-2011 à 18:23:22  profilanswer
 

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 :
  1. my @content = $doc->getElementsByTagName ("Content" );
  2. foreach $element (@content) {
  3.             $id_cont = $element->getAttribute ("id" );
  4.             $title_cont = $element->getAttribute ("title" );
  5. }


 
 
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 :
  1. <Content id="TST10428" title="Il était une fois" duration="3600" action="override">
  2.    <EpgDescription locale="fr_FR">
  3.      <EpgElement key="Title">Il était une fois</EpgElement>
  4.      <EpgElement key="Synopsis"></EpgElement>
  5.      <EpgElement key="Description"/>
  6.      <EpgElement key="Copyright">©</EpgElement>
  7.      <EpgElement key="ShortTitle">Il était une fois</EpgElement>
  8.    </EpgDescription>
  9.    <EpgDescription>
  10.      <EpgElement key="Aspect">4:3</EpgElement>
  11.      <EpgElement key="Definition">SD</EpgElement>
  12.      <EpgElement key="AudioMode">Nicam Stereo</EpgElement>
  13.      <EpgElement key="IsRecordable">0</EpgElement>
  14.      <EpgElement key="Year">1998</EpgElement>
  15.      <EpgElement key="Countries">FR</EpgElement>
  16.      <EpgElement key="Categories">Humour</EpgElement>
  17.      <EpgElement key="Rating">0</EpgElement>
  18.      <EpgElement key="Actors"></EpgElement>
  19.      <EpgElement key="Directors"></EpgElement>
  20.      <EpgElement key="Producers"></EpgElement>
  21.      <EpgElement key="Studio"></EpgElement>
  22.      <EpgElement key="Language">fra</EpgElement>
  23.      <EpgElement key="PromoImage">image.jpg</EpgElement>
  24.      <EpgElement key="BestSalesIndex"/>
  25.    </EpgDescription>
  26.    <Media id="TST60626" title="Il était une fois" fileName="test.mpg" frameDuration="90000" fileSize="1" comment="comment" action="override"/>
  27.  </Content>


 
Merci d'avance.

n°2118421
gilou
Modérateur
Modzilla
Posté le 27-12-2011 à 13:31:16  profilanswer
 

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+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2118426
Sethenssen
Posté le 27-12-2011 à 14:29:41  profilanswer
 

Merci Gilou,
Je trépigne d'impatience de tester cela

n°2118526
Sethenssen
Posté le 28-12-2011 à 10:27:45  profilanswer
 

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 :
  1. <VODContentProvider id="TST" name="TEST" scheduleDate="2011-12-26T10:54:34Z">
  2. <Content id="TST15815" title="Titre film 01" duration="5940" action="override">
  3.    <EpgDescription locale="fr_FR">
  4.      <EpgElement key="Title">Titre film 01</EpgElement>
  5.      <EpgElement key="ShortTitle">Titre film 01</EpgElement>
  6.    </EpgDescription>
  7.    <EpgDescription>
  8.      <EpgElement key="Definition">SD</EpgElement>
  9.      <EpgElement key="PromoImage">15815.jpg</EpgElement>
  10.    </EpgDescription>
  11.    <Media id="TST190334" title="Titre film 01" fileName="15815_3800.mpg" frameDuration="148500" fileSize="1" comment="comments" action="override"/>
  12.  </Content>
  13. <Content id="TST15812" title="Titre film 02" duration="6960" action="override">
  14.    <EpgDescription locale="fr_FR">
  15.      <EpgElement key="Title">Titre film 02</EpgElement>
  16.      <EpgElement key="ShortTitle">Titre film 02</EpgElement>
  17.    </EpgDescription>
  18.    <EpgDescription>
  19.      <EpgElement key="Definition">SD</EpgElement>
  20.      <EpgElement key="PromoImage">15812.jpg</EpgElement>
  21.    </EpgDescription>
  22.    <Media id="TST193011" title="Titre film 02" fileName="test02.mpg" frameDuration="174000" fileSize="1" comment="comments" action="override"/>
  23.  </Content>
  24. <VodItem id="TST190334" action="override" title="Titre film 01" broadcasterId="TST" contentRef="TST15815" previewDate="2011-11-30T12:00:01Z" nodeRefList="TSTFRA1002">
  25.    <EpgDescription locale="fr_FR">
  26.      <EpgElement key="Title">Titre film 01</EpgElement>
  27.      <EpgElement key="DisplayPriority">100</EpgElement>
  28.    </EpgDescription>
  29.    <Period start="2011-12-31T12:00:01Z" end="2012-11-30T00:00:00Z"/>
  30.  </VodItem>
  31. <VodItem id="TST193011" action="override" title="Titre film 02" broadcasterId="TST" contentRef="TST15812" previewDate="2011-11-30T12:00:01Z" nodeRefList="TSTFRA1002">
  32.    <EpgDescription locale="fr_FR">
  33.      <EpgElement key="Title">Titre film 02</EpgElement>
  34.      <EpgElement key="DisplayPriority">100</EpgElement>
  35.    </EpgDescription>
  36.    <Period start="2011-12-31T12:00:01Z" end="2012-12-31T00:00:00Z"/>
  37.  </VodItem>
  38. </VODContentProvider>


 
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 :
  1. TST15815|Titre film 01|SD|15815.jpg|TST15815|TST190334|2012-11-30T00:00:00Z
  2. TST15812|Titre film 02|SD|15812.jpg|TST15812|TST193011|2012-12-31T00:00:00Z


 
Hors, quand je rajoute le tableau @Periods j'obtiens:

Code :
  1. TST15815|Titre film 01|SD|15815.jpg|TST15815|TST190334|2012-11-30T00:00:00Z
  2. TST15815|Titre film 01|SD|15815.jpg|TST15815|TST190334|2012-12-31T00:00:00Z
  3. TST15812|Titre film 02|SD|15812.jpg|TST15812|TST193011|2012-11-30T00:00:00Z
  4. TST15812|Titre film 02|SD|15812.jpg|TST15812|TST193011|2012-12-31T00:00:00Z


 
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 :
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4.  
  5. use XML::DOM;
  6.  
  7. my $SCRIPT_DIR="/cygdrive/d/_.compil/can/";
  8. print $SCRIPT_DIR."\n\n";
  9.  
  10. opendir C_DIR, "$SCRIPT_DIR" or die "Message : $!\n";
  11. my @INPUT_FILES = grep /.*\.xml/ , readdir C_DIR;
  12. foreach my $files (@INPUT_FILES)    {
  13.     my $parser = new XML::DOM::Parser();
  14.     my $doc;
  15.     eval { $doc = $parser->parsefile($SCRIPT_DIR.$files); } ;
  16.     if ($@) {
  17.         print "WARNING:       $files:                    not well-formed\n";
  18.         next;
  19.     }
  20.     print "Traitement de: $files\n";
  21.     my @Contents = $doc->getElementsByTagName ("Content" );
  22.     foreach my $Content (@Contents) {
  23.         my $id_cont = $Content->getAttribute ("id" );
  24.         my $title_cont = $Content->getAttribute ("title" );
  25.         my @EpgElements = $Content->getElementsByTagName ('EpgElement');
  26.         foreach my $EpgElement (@EpgElements) {
  27.             next if ($EpgElement->getAttribute('key') ne 'Definition');
  28.             my $definition = $EpgElement->getFirstChild()->getNodeValue();
  29.             foreach my $EpgElement (@EpgElements) {
  30.                 next if ($EpgElement->getAttribute('key') ne 'PromoImage');
  31.                 my $promo_image = $EpgElement->getFirstChild()->getNodeValue();
  32.                 my @VodItems = $doc->getElementsByTagName ("VodItem" );
  33.                 foreach my $VodItem (@VodItems) {
  34.                     my $voditem_contRef = $VodItem->getAttribute ("contentRef" );
  35.                     my $voditem_id = $VodItem->getAttribute ("id" );
  36.                     if ($voditem_contRef eq $id_cont) {
  37.                         my @Periods = $doc->getElementsByTagName ("Period" );
  38.                         foreach my $Period (@Periods) {
  39.                             my $enddate = $Period->getAttribute ("end" );
  40.                             print "$id_cont|$title_cont|$definition|$promo_image|$voditem_contRef|$voditem_id|$enddate\n";
  41.                         }
  42.                     }
  43.                 }
  44.             }
  45.         }
  46.     }
  47.     $doc->dispose;
  48. }
  49. __END__


Message édité par Sethenssen le 28-12-2011 à 10:29:23
n°2118542
gilou
Modérateur
Modzilla
Posté le 28-12-2011 à 12:35:38  profilanswer
 

:hello:  
 
Déjà une chose:
Quand tu veux ça

Citation :

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


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+,


Message édité par gilou le 28-12-2011 à 12:36:57

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2118558
gilou
Modérateur
Modzilla
Posté le 28-12-2011 à 14:15:51  profilanswer
 

Tiens, voici comment faire en passant par un hash (ou plutôt un hash de hash en fait)

Code :
  1. #!/usr/local/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use XML::DOM;
  7.  
  8. my $parser = XML::DOM::Parser->new();
  9. my $doc = $parser->parsefile('VOD.xml');
  10. my %record;
  11. my @Contents = $doc->getElementsByTagName ('Content');
  12. foreach my $Content (@Contents) {
  13.  my $id = $Content->getAttribute('id');
  14.  my @EpgElements = $Content->getElementsByTagName ('EpgElement');
  15.  foreach my $EpgElement (@EpgElements) {
  16.    $record{$id}{$EpgElement->getAttribute('key')} = $EpgElement->getFirstChild()->getNodeValue();
  17.  }
  18. }
  19. my @VodItems = $doc->getElementsByTagName ('VodItem');
  20. foreach my $VodItem (@VodItems) {
  21.  my $id = $VodItem->getAttribute('contentRef');
  22.  $record{$id}{'Vodid'} = $VodItem->getAttribute('id');
  23.  my @Periods = $VodItem->getElementsByTagName ('Period');
  24.  $record{$id}{'end'} = $Periods[0]->getAttribute('end');
  25. }
  26. $doc->dispose;
  27.  
  28. foreach my $id (reverse (sort (keys %record))) {
  29.  print $id, "|",
  30.    $record{$id}{'Title'}, "|",
  31.    $record{$id}{'Definition'}, "|",
  32.    $record{$id}{'PromoImage'}, "|",
  33.    $id, "|",
  34.    $record{$id}{'Vodid'}, "|",
  35.    $record{$id}{'end'}, "\n";
  36. }


 

C:\Perl>perl VOD.pl
TST15815|Titre film 01|SD|15815.jpg|TST15815|TST190334|2012-11-30T00:00:00Z
TST15812|Titre film 02|SD|15812.jpg|TST15812|TST193011|2012-11-30T00:00:00Z


 
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+,


Message édité par gilou le 28-12-2011 à 15:13:40

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2118562
Sethenssen
Posté le 28-12-2011 à 14:40:11  profilanswer
 

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

n°2118565
gilou
Modérateur
Modzilla
Posté le 28-12-2011 à 14:44:26  profilanswer
 

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+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2118566
gilou
Modérateur
Modzilla
Posté le 28-12-2011 à 14:47:04  profilanswer
 

Bon, sinon, si tu peux avoir plusieurs VodItems referençant un même Content, il faudrait un code du style suivant:
 

Code :
  1. #!/usr/local/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5.  
  6. use XML::DOM;
  7.  
  8. my $parser = XML::DOM::Parser->new();
  9. my $doc = $parser->parsefile('VOD.xml');
  10. my %record;
  11. my @Contents = $doc->getElementsByTagName ('Content');
  12. foreach my $Content (@Contents) {
  13.  my $id = $Content->getAttribute('id');
  14.  my @EpgElements = $Content->getElementsByTagName ('EpgElement');
  15.  foreach my $EpgElement (@EpgElements) {
  16.    $record{$id}{$EpgElement->getAttribute('key')} = $EpgElement->getFirstChild()->getNodeValue();
  17.  }
  18. }
  19. my %vrecord;
  20. my @VodItems = $doc->getElementsByTagName ('VodItem');
  21. foreach my $VodItem (@VodItems) {
  22.  my $id = $VodItem->getAttribute('id');
  23.  $vrecord{$id}{'contentRef'} = $VodItem->getAttribute('contentRef');
  24.  my @Periods = $VodItem->getElementsByTagName ('Period');
  25.  $vrecord{$id}{'end'} = $Periods[0]->getAttribute('end');
  26. }
  27. $doc->dispose;
  28.  
  29. foreach (reverse (sort (keys %vrecord))) {
  30.  my $id = $vrecord{$_}{'contentRef'};
  31.  print $id, "|",
  32.    $record{$id}{'Title'}, "|",
  33.    $record{$id}{'Definition'}, "|",
  34.    $record{$id}{'PromoImage'}, "|",
  35.    $id, "|",
  36.    $_, "|",
  37.    $vrecord{$_}{'end'}, "\n";
  38. }


 
A+,


Message édité par gilou le 28-12-2011 à 14:51:11

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2118573
Sethenssen
Posté le 28-12-2011 à 15:45:43  profilanswer
 

Grand merci pour ton aide Gilou !
Je vais m'atteler à examiner tout cela.

n°2118733
Sethenssen
Posté le 29-12-2011 à 18:09:09  profilanswer
 

Cela fonctionne à la perfection.
Encore merci pour m'avoir débloqué.

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  [Résolu] XML::DOM Comment récupérer une donnée?

 

Sujets relatifs
[RESOLU] JQuery appel ajax, récuperer la valeur d'une selectboxRécupérer valeur d'un select en fonction de son id
Comment récupérer le son d'une vidéo en texteConversion d'un fichier XML en fichier WXR
[VB] Modifier un fichier XMLTransformer du XML en WSDL avec XSLT ?
Comment récupérer la valeur choisie dans <select> ou <option>?Afficher la derniere ligne entrée dans une base de donnée phpmyadmin
VBA CATIA V5 - Récupérer la langue de l'interface utilisateur 
Plus de sujets relatifs à : [Résolu] XML::DOM Comment récupérer une donnée?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR