2010-01-17 5 views
2

J'ai un fichier XML, dont une partie se présente comme suit:Pourquoi ne puis-je pas accéder aux éléments d'un fichier XML avec XPath dans XML :: LibXML?

<wave waveID="1"> 
    <well wellID="1" wellName="A1"> 
     <oneDataSet> 
     <rawData>0.1123975676</rawData> 
     </oneDataSet> 
    </well> 
    ... more wellID's and rawData continues here... 

Je suis en train d'analyser le fichier avec Libxml de Perl et de sortie de la wellName et l'rawData en utilisant les éléments suivants:

use XML::LibXML; 
    my $parser = XML::LibXML->new(); 
    my $doc = $parser->parse_file('/Users/johncumbers/Temp/1_12-18-09-111823.orig.xml'); 
    my $xc = XML::LibXML::XPathContext->new($doc->documentElement() ); 
    $xc->registerNs('ns', 'http://moleculardevices.com/microplateML'); 

      my @n = $xc->findnodes('//ns:wave[@waveID="1"]'); #xc is xpathContent 
     # should find a tree from the node representing everything beneath the waveID 1 
     foreach $nod (@n) { 
      my @c = $nod->findnodes('//rawData'); #element inside the tree. 
      print @c; 
     } 

Il n'imprime rien en ce moment et je pense avoir un problème avec mes instructions Xpath. Pouvez-vous m'aider à résoudre le problème, ou pouvez-vous me montrer comment résoudre les problèmes de xpath? Merci.

+0

Je ne connais pas cette bibliothèque XML, mais ce que je remarque est le préfixe d'espace de noms 'ns:'. Qu'avez-vous déclaré dans le contexte XPath? Votre fichier XML a-t-il une déclaration d'espace de nom par défaut? (Il est probablement faux d'utiliser 'ns:' dans un endroit et pas de préfixe dans l'autre.) –

+0

Merci Kevin, j'ai ajouté les lignes d'espace de noms à la question originale. J'ai essayé: '// ns: rawData' comme vous le suggérez, mais obtenez "error: xmlXPathCompiledEval: évaluation a échoué" – John

+0

désolé, j'ai mal lu votre commentaire, le fichier XML original a une déclaration d'espace de noms John

Répondre

2

Au lieu d'utiliser findnodes dans la boucle, utilisez getElementsByTagName():

my @c = $nod->getElementsByTagName('rawData'); 

Voici quelques autres méthodes pratiques pour utiliser le traitement à un tableau @c:

$c[0]->toString; # <rawData>0.1123975676</rawData> 
$c[0]->nodeName; # rawData 
$c[0]->textContent; # 0.1123975676 
2

Si l'élément « vague » est en un espace de noms puis l'élément 'rawData' est également ainsi vous devez probablement utiliser

foreach $nod (@n) { 
    my @c = $xc->findnodes('descendant::ns:rawData', $nod); #element inside the tree. 
    print @c; 
} 
Questions connexes