2012-04-03 9 views
1

ich den folgenden Code haben:Python 2.7 libxml2, XPath, extrahieren XML-Attribute

import libxml2 
import sys 

def xpath_grep(query, file): 
    doc = libxml2.parseDoc(file) 
    for matched_region in doc.xpathEval(query): 
     matched_region.saveTo(sys.stdout, format = True) # add match to stdout 

if __name__ == '__main__': 
    if len(sys.argv) <= 1: 
     # default arguments 
     query = "data(bn/variable/@name)" 
     files = ["burglary_bn.xml"] 
    else: 
     query = sys.argv[1] 
     files = sys.argv[2:] 

    for xml_file in files: 
     xpath_grep(query, file(xml_file).read()) 

Während ich die "Daten" glauben Funktion sollte den Wert des XML-Attribut abzurufen, ist es nicht. Stattdessen gibt es mir einen Fehler:

xmlXPathCompOpEval: function data not found 
Unregistered function 
... 
libxml2.xpathError: xmlXPathEval() failed 

Was mache ich falsch?

EDIT: Dokumentation für die XPath-Datenfunktion finden Sie hier: http://www.w3.org/TR/xpath-functions/#func-data

+0

Die Funktion 'data()' ist nur in XPath 2.0-Prozessoren verfügbar - sie wird nicht von XPath 1.0-Prozessoren wie libxml implementiert. –

Antwort

1

Sie sollten keine Xpath-Funktion aufrufen müssen, um den Wert eines Attributs zu erhalten. Um zum Beispiel das folgende XML-Dokument angegeben:

<doc> 
    <section> 
    <person name="bob" color="blue"/> 
    </section> 
</doc> 

Dieser Python-Code erhalten Sie mir den Wert des name Attribut:

>>> doc = libxml2.parseDoc(open('input.xml').read()) 
>>> str(doc.xpathEval('//person/@name')[0].children) 
'bob' 

Ich habe noch nie das libxml2 Modul vor, so gibt es eine sein kann, besserer Weg. Ich benutze immer das lxmletree Modul, mit denen wir die gleiche Sache wie dies bewerkstelligen könnte:

>>> import lxml.etree as etree 
>>> d = etree.parse(open('foo.xml')) 
>>> d.xpath('//person/@name')[0] 
'bob' 

Wenn Sie es verwenden können, die ElementTree (etree) API viel einfacher zu handhaben ist.

0

Sie nicht die Funktionsdaten definiert haben(), oder zumindest haben Sie nicht das richtige Modul importieren, die Daten Submodul Namen hat . In Ihrem Code:

query = "data(bn/variable/@name)" 

sieht seltsam. Warum rufst du eine Funktion wie diese auf? Was genau würde die Datenfunktion tun, wenn sie verfügbar wäre?

+0

Daten sind eine XPath-Funktion. Bitte lesen Sie die XPath-Dokumentation. – BlackSheep

+0

da er ** data() ** als Standalone-Funktion bezeichnete, denke ich, dass es sinnvoll ist, seine Frage zu klären. @ BackSheep: Downvote meine Antwort ist kein schöner Action-Gedanke. – hungnv

1

data() ist eine XPath 2.0-Funktion und ist nicht in einem XSLT 1.0-Prozessor wie libxml implementiert.

Sie müssen den folgenden Ausdruck bewerten:

bn/variable/@name 

und iterativ (in Python) erhalten den String-Wert jedes ausgewählten Knotens.