findtext и xpath ничего не возвращают из моего разобранного XML-документа - PullRequest
0 голосов
/ 22 марта 2012

Я использую lxml.etree.parse в django для анализа некоторого контента из внешнего 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()"),

Любая помощь приветствуется.

1 Ответ

1 голос
/ 22 марта 2012

Вы не учитываете пространство имен 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() о том, какой префикс вы будете использовать для какого пространства имен, и, следовательно, о втором параметре.

...