【问题标题】:findtext and xpath not returning anything from my parsed xml documentfindtext 和 xpath 没有从我解析的 xml 文档中返回任何内容
【发布时间】:2012-04-07 07:59:46
【问题描述】:

我在 django 中使用 lxml.etree.parse 来解析来自外部 rss 提要的一些内容,并使用 findall 来解决命名空间问题。

我可以遍历刚刚找到的结果,但是我无法显示结果中的任何文本。

这是我试图从中抓取的 xml 文件的样子:

<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Open Library : Author Name</title>
    <link href="http://www.somedomain.org/people/atom/author_name" rel="self"/>
    <updated>2012-03-20T16:41:00Z</updated>
    <author>
        <name>somedomain.org</name>
    </author>
    <id>tag:somedomain.org,2007:/person_feed/123456</id>
    <entry>
        <link href="http://www.somedomain.org/roll_call/show/1234" rel="alternate"/>
        <id>
        tag:somedomain.org,2012-03-20:/roll_call_vote/1234
        </id>
        <updated>2012-03-20T16:41:00Z</updated>
        <title>Once upon a time</title>
        <content type="html">
        This is a book full of words
        </content>
    </entry>
</feed>

这是我在 django 中的视图:

def openauthors(request):

    tree = lxml.etree.parse("http://www.somedomain.org/people/atom/author_name")
    namespace = "{http://www.w3.org/2005/Atom}"
    listings = tree.findall("{http://www.w3.org/2005/Atom}entry")

    listings_info = []

    for listing in listings:
        this_value = {
            "link": listing.findtext("content"),
            "title": listing.findtext("feed/content"),
            "content": listing.findtext("content"),
            }

        listings_info.append(this_value)


    json_listings = '{"listings":' + simplejson.dumps(listings_info) + '}'

    if("callback" in request.GET.keys()):
        callback = request.GET["callback"]
    else:
        callback = None

    if(callback):
        response = HttpResponse("%s(%s)" % (
                callback,
                simplejson.dumps(listings_info)
                ), mimetype="application/json"
            )
    else:
        response = HttpResponse(json_listings, mimetype="application/json")
    return response

我还尝试使用xpath 代替findtext 进行以下操作,但得到了相同的结果。

    "link":listing.xpath("link/text()"),
    "title":listing.xpath("entry/link/text()"),
    "content":listing.xpath("content/text()"),

感谢任何帮助。

【问题讨论】:

    标签: python xml django xpath elementtree


    【解决方案1】:

    您没有考虑 XML 命名空间。

    tree = lxml.etree.parse("http://www.somedomain.org/people/atom/author_name")
    xmlns = {"atom": "http://www.w3.org/2005/Atom"}
    listings = tree.xpath("//atom:entry", namespaces=xmlns)
    
    listings_info = []
    
    for listing in listings:
        listings_info.append({
            "link": listing.xpath("./atom:link/@href", namespaces=xmlns),
            "title": listing.xpath("./atom:title", namespaces=xmlns),
            "content": listing.xpath("./atom:content", namespaces=xmlns),
        })
    

    您必须定义一个前缀(即使您的 XML 中没有)并在您的 XPath 表达式中使用它。这意味着您必须告知.xpath() 您将为哪个命名空间使用什么前缀,因此是第二个参数。

    【讨论】:

    • 这似乎很有效,但是我不得不将/text() 发送到"title": listing.xpath("./atom:title", namespaces=xmlns), 以使其成为"title": listing.xpath("./atom:title/text()", namespaces=xmlns), 以及内容的一个。谢谢!
    • @bigmike7801 没错。我不确定您是否需要这些元素或其内容。
    猜你喜欢
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 2022-01-03
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多