Python xpath不工作?

Python xpath不工作?,python,xml,xpath,xml-namespaces,amara,Python,Xml,Xpath,Xml Namespaces,Amara,好了,这开始让我有点发疯了。我已经尝试了几种Python的xml/xpath库,但找不到一种简单的方法来获取一个“title”元素 最近的尝试如下所示(使用Amara): 但这不会打印出任何内容。我的XML如下所示: 如果我尝试/*而不是///title,它会按预期返回所有内容。我知道XML中有titles,那么有什么问题呢?是名称空间还是什么?如果是,我如何修复它 似乎无法在没有前缀的情况下使其工作,但这确实有效: def view(req, url): req.content_ty

好了,这开始让我有点发疯了。我已经尝试了几种Python的xml/xpath库,但找不到一种简单的方法来获取一个“title”元素

最近的尝试如下所示(使用Amara):

但这不会打印出任何内容。我的XML如下所示:

如果我尝试
/*
而不是
///title
,它会按预期返回所有内容。我知道XML中有
title
s,那么有什么问题呢?是名称空间还是什么?如果是,我如何修复它


似乎无法在没有前缀的情况下使其工作,但这确实有效:

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')))

您可能只需要考虑正在处理的文档的名称空间

我建议在Amara中查找如何处理名称空间:

编辑:我用你的代码片段做了一些编辑。我不知道您使用的是哪一版本的Amara,但根据文档,我尽可能地适应它:

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')))

它确实是名称空间。在lxml文档中查找有点棘手,但以下是您的操作方法:

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

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

在这两种情况下,你都会得到标题。

这对我没有什么帮助。如果我事先不知道名称空间呢?如果我真的不关心名称空间是什么呢?您说过您的xml文档与您链接的文档类似。链接到的名称空间包含名称空间。使用名称空间是有原因的——当然,您可以从xml文档中去掉名称空间,这样您就不必担心了。否则您必须对此负责。@“关心名称空间是什么”-您可能可以解析xmlns属性并注册该值。对,除非更改原始xml源,否则您无法避免处理名称空间。我认为名称空间的全部要点是避免与重复的节点名称/属性发生冲突。在XPath和XML标准中,如果我使用这些技术,我会遵守这些标准。编写XML时,可以在顶部为整个文档定义名称空间。那么,为什么在查询XML时不能指定要使用的默认名称空间呢?我98%确定其他库允许您这样做…如果我事先不知道名称空间怎么办?我只想去掉em。它们甚至可能是在文档的中间定义的(在div或其他东西上)。为什么不能解析xmlns属性呢?XML是一种完全通用的数据交换协议。如果您不知道数据的格式,通常无法对数据做很多有用的事情,因为您不知道数据的含义。另外,如果您事先不知道名称空间的结构,那么必须注意并解析名称空间,无论它们出现在哪里。然而,这是一个广义的XML解析问题,情况极不可能如此。因此,我认为您确实知道相当多的结构,包括名称空间是什么,或者它们可能被定义在哪里。所以:没问题。了解结构可能包括名称空间总是相同的,并且总是可以安全地忽略。在这种情况下,您可以先从文档中筛选出它。但是再一次,在这种情况下,您知道那里有一个名称空间,并且您确实关心它,因为您过滤掉了它。如果您使用的是
lxml
,那么您可以使用
doc.getroot().nsmap
获取名称空间,然后将其传递给您的
.xpath()
调用。除了对默认名称空间没有帮助之外,您仍然需要手动添加默认名称空间。您可以通过请求生成XML的人删除名称空间来删除该名称空间。否则你需要处理它。这可以通过编辑文件来完成,但是,您也可以使用regexps或Python中的简单“finds”来处理整个文件。。。但是处理XML的健壮方法是使用XML解析器。包括名称空间。另一方面,这个问题已经在谷歌的第1页上排名为“amara get root node”。。。不到一个小时,嘘
title_finder = etree.ETXPath('//{http://www.w3.org/2005/Atom}title')
title_finder(doc)