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

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

Marsh Posté le 22-09-2011 à 00:17:09    

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
Reply

Marsh Posté le 22-09-2011 à 00:17:09   

Reply

Marsh Posté le 22-09-2011 à 02:26:55    

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é!  --
Reply

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.

Reply

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


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é!  --
Reply

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

Reply

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 :
  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
Reply

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 :
  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
Reply

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


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

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 :
  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
Reply

Marsh Posté le 22-09-2011 à 21:12:18    

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é!  --
Reply

Marsh Posté le 22-09-2011 à 21:12:18   

Reply

Marsh Posté le 22-09-2011 à 22:10:39    

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

Reply

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 :
  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.

Reply

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


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-12-2011 à 14:29:41    

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

Reply

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 :
  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
Reply

Marsh Posté le 28-12-2011 à 12:35:38    

: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é!  --
Reply

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 :
  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é!  --
Reply

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

Reply

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


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

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 :
  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é!  --
Reply

Marsh Posté le 28-12-2011 à 15:45:43    

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

Reply

Marsh Posté le 29-12-2011 à 18:09:09    

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

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed