Perl XML:: LibXML: findnode vs. findvalue vs. find - Quelle est la différence?
j'utilise XML::LibXML, et j'ai simplement besoin de compter les noeuds spécifiés par une expression XPath.
L'utilisation de l'une ou l'autre des deux premières lignes de code ci-dessous donne ce que je cherche. Je peux utiliser le count fonction XPath avec l'une ou l'autre findvalue ou find mais pas findnodes (oui, je sais, parce qu'elle renvoie une liste).
my $node_cnt = $dom->findvalue("count($xpath_str)"); # WORKS!
my $node_cnt = $dom->find("count($xpath_str)"); # WORKS!
my @node_cnt = $dom->findnodes("count($xpath_str)"); # count doesn't work!
ce qui m'amène à une question générale lancinante: Quelle est la différence entre les trois types? Dans le de la documentation, il dit:
$string = $node->findvalue($xpath)
$result = $node->find($xpath)
@nodes = $node->findnodes($xpath_expression)
Est-il vraiment une différence entre l'argument
$xpath_expressionvs$xpathdans la documentation?pour les deux retournant un scalaire, Quelle est la différence?
j'essaie de comprendre la signification de l'utilisation d'un type de find par rapport à l'autre - merci!
1 réponses
la différence est le type de valeur que les méthodes renvoient.
findnodesest utilisée pour retourner une liste de nœuds. Si la méthode est appelée dans le contexte list, alors elle renvoie une liste d'objets du type approprié, tels queXML::LibXML::Element,XML::LibXML::Textetc. Si elle est appelée dans le contexte scalaire, elle renvoie unXML::LibXML::NodeListobjet qui contient les mêmes informations.ne peut pas être utilisé pour renvoyer une expression arbitraire, par exemple
$dom->findnodes('42')retournera rien. Vous ne pouvez obtenir qu'une liste des noeuds de documents à partir de cette méthode.findvalueest utilisé pour retourner un texte simple ou numérique valeur, c'est-à-dire pas un noeud XML. Si vous passez une expression XPath qui évalue à une liste de noeuds, alors elle convertit cette liste en texte en concaténant tous les noeuds de texte dans n'importe lequel des noeuds de la liste.findpeut rapporter n'importe quoi. Il retournera une liste de noeuds comme unXML::LibXML::NodeListobjet, une valeur numérique comme unXML::LibXML::Numberobjet, une chaîne littérale comme unXML::LibXML::Literalobjet etc. Contrairement àfindnodes,toujours renvoie une seule valeur scalaire, même si elle est appelée dans le contexte list.je n'ai jamais choisi d'utiliser
find. Il semble qu'il est prévu comme un piège tous quand vous ne savez pas quel genre de résultat à attendre.
Par exemple, vous auriez probablement eu envie d'écrire my $nrecs = $dom->findvalue('count(/root/record)') pour obtenir le nombre d'enregistrements dans la racine élément. $nrecs serait une valeur numérique perl simple.
d'autre part, pour obtenir un liste de ces enregistrements, vous utiliseriez my @records = $dom->findnodes('/root/record'). Maintenant @records contient un nombre de XML::LibXML::Element objets.
dans vos exemples,
my $node_cnt = $dom->findvalue("count($xpath_str)"); # WORKS!
jeux $node_cnt à un nombre Perl simple, alors que celui-ci
my $node_cnt = $dom->find("count($xpath_str)"); # WORKS!
configure $node_cntXML::LibXML::Number de l'objet, ce qui arrive à stringify (lors de l'impression) de la même manière que la précédente déclaration. Prouver vous-même en impression print ref $node_cnt dans les deux cas.
my @node_cnt = $dom->findnodes("count($xpath_str)"); # count doesn't work!
échoue parce que le XPath count évalue à un nombre, pas à un noeud XML (il ne fait pas partie de L'arborescence XML). Il n'y a aucun moyen de convertir des nombres en noeuds, donc le résultat est une liste vide. Si c'était l'inverse, et nous avions appelé findvalue sur une expression évaluée à une liste de noeuds, alors il y a une façon vaguement sensible de convertir en valeur texte et findvalue fait de son meilleur et renvoie la concaténation de tous les nœuds de texte contenue par les noeuds de la liste.