2009-10-18 11 views
0

D'accord, cela commence à me rendre un peu fou. J'ai essayé plusieurs bibliothèques xml/xpath pour Python, et je n'arrive pas à trouver un moyen simple d'obtenir un élément "title" de stinkin.Python xpath ne fonctionne pas?

La dernière tentative ressemble à ceci (en utilisant Amara):

def view(req, url): 
    req.content_type = 'text/plain' 
    doc = amara.parse(urlopen(url)) 
    for node in doc.xml_xpath('//title'): 
    req.write(str(node)+'\n') 

Mais qui imprime rien. Mon XML ressemble à ceci: http://programanddesign.com/feed/atom/

Si j'essaie //* au lieu de //title il retourne tout comme prévu. Je sais que le XML a title là-dedans, alors quel est le problème? Est-ce l'espace de noms ou quelque chose? Si oui, comment puis-je le réparer?


peut sembler ne pas le faire fonctionner sans préfixe, mais cela fonctionne:

def view(req, url): 
    req.content_type = 'text/plain' 
    doc = amara.parse(url, prefixes={'atom': 'http://www.w3.org/2005/Atom'}) 
    req.write(str(doc.xml_xpath('//atom:title'))) 
+0

Vous pouvez vous débarrasser de l'espace de noms en demandant à celui qui génère le code XML de s'en débarrasser. Sinon, vous devez vous en occuper. Cela peut être fait en éditant le fichier, mais encore une fois, vous pouvez gérer tout le fichier avec des regexps, ou de simples "trouvailles" en Python ... Mais la façon robuste de gérer XML est avec un analyseur XML. Y compris les espaces de noms. –

+0

Sur une note de côté, cette question se classe déjà sur la page 1 sur google pour la requête "amara get root node" ... en moins d'une heure, sheesh – mpen

Répondre

1

Vous avez probablement juste de prendre en compte l'espace de noms du document que vous avez affaire à .

Je suggérerais regardant la façon de traiter avec les espaces de noms à Amara:

http://www.xml3k.org/Amara/Manual#namespaces

Edit: En utilisant l'extrait de code que j'ai fait quelques modifications. Je ne sais pas quelle version de Amara vous utilisez, mais sur la base des documents que j'essayé de tenir compte autant que possible:

def view(req, url): 
    req.content_type = 'text/plain' 
    ns = {u'f' : u'http://www.w3.org/2005/Atom', 
     u't' : u'http://purl.org/syndication/thread/1.0'} 
    doc = amara.parse(urlopen(url), prefixes=ns) 
    req.write(str(doc.xml_xpath(u'f:title'))) 
+0

Cela ne m'aide pas vraiment. Que faire si je ne connais pas les espaces de noms à l'avance? Que faire si je ne me soucie pas vraiment de l'espace de noms? – mpen

+1

Vous avez dit que votre document xml est similaire à celui auquel vous êtes lié. Celui auquel vous avez lié contient un espace de noms. Il y a un * reason * namespaces sont utilisés - bien sûr, vous pouvez vous débarrasser de votre espace de noms à partir de votre document XML, alors vous n'avez pas à vous en préoccuper. Sinon, vous devez en tenir compte. –

+0

@ "attention à l'espace de noms" - vous pouvez probablement analyser l'attribut xmlns et simplement enregistrer cette valeur. –

1

Il est en effet les espaces de noms. Il était un peu difficile à trouver dans les lxml docs, mais voici comment vous le faites:

from lxml import etree 
doc = etree.parse(open('index.html')) 
doc.xpath('//default:title', namespaces={'default':'http://www.w3.org/2005/Atom'}) 

Vous pouvez aussi le faire:

title_finder = etree.ETXPath('//{http://www.w3.org/2005/Atom}title') 
title_finder(doc) 

Et vous obtiendrez les titres de retour dans les deux cas .

+0

Que faire si je ne connais pas les espaces de noms à l'avance? Je veux juste me débarrasser d'em. Ils pourraient même être définis à mi-chemin dans le document (sur un div ou quelque chose). – mpen

+0

pourquoi ne pas simplement analyser l'attribut xmlns? –

+2

XML est un protocole d'échange de données entièrement générique. Si vous ne connaissez pas le format, vous ne pouvez généralement pas faire beaucoup de choses utiles avec les données, car vous ne savez pas ce que les données signifient. Aussi, si vous ne connaissez pas la structure à l'avance, alors vous devez prendre soin et analyser les espaces de noms où qu'ils apparaissent. Cependant, il s'agit d'un problème d'analyse syntaxique XML généralisé, et il est fort improbable que ce soit le cas. Donc, je pense que vous connaissez un peu de la structure, y compris soit ce que sont les espaces de noms, ou où ils sont susceptibles d'être définis. Donc: Pas de problème. –