Xpath wie Abfrage für verschachtelte Python-Wörterbücher

Gibt es eine Möglichkeit, eine XPath-Typ-Abfrage für verschachtelte Python-Wörterbücher zu definieren.

Etwas wie das:

foo = { 'spam':'eggs', 'morefoo': { 'bar':'soap', 'morebar': {'bacon' : 'foobar'} } } print( foo.select("/morefoo/morebar") ) >> {'bacon' : 'foobar'} 

Ich musste auch verschachtelte Listen auswählen;)

Das kann man leicht mit @ jellybeans Lösung machen:

 def xpath_get(mydict, path): elem = mydict try: for x in path.strip("/").split("/"): try: x = int(x) elem = elem[x] except ValueError: elem = elem.get(x) except: pass return elem foo = { 'spam':'eggs', 'morefoo': [{ 'bar':'soap', 'morebar': { 'bacon' : { 'bla':'balbla' } } }, 'bla' ] } print xpath_get(foo, "/morefoo/0/morebar/bacon") 

[EDIT 2016] Diese Frage und die akzeptierte Antwort sind alt. Die neueren Antworten können die Arbeit besser machen als die ursprüngliche Antwort. Allerdings habe ich sie nicht getestet, damit ich die akzeptierte Antwort nicht ändern werde.

7 Solutions collect form web for “Xpath wie Abfrage für verschachtelte Python-Wörterbücher”

Nicht gerade schön, aber du könntest auch etw

 def xpath_get(mydict, path): elem = mydict try: for x in path.strip("/").split("/"): elem = elem.get(x) except: pass return elem 

Dies unterstützt nicht xpath Zeug wie Indizes, natürlich … nicht zu erwähnen, die / Key-Trap Unutbu angegeben.

Eine der besten Bibliotheken, die ich identifizieren konnte, die außerdem sehr aktiv entwickelt ist, ist ein extrahiertes Projekt von boto: JMESPath . Es hat eine sehr starke Syntax von Dingen, die normalerweise Seiten von Code zum Ausdruck bringen würde.

Hier sind einige Beispiele:

 search('foo | bar', {"foo": {"bar": "baz"}}) -> "baz" search('foo[*].bar | [0]', { "foo": [{"bar": ["first1", "second1"]}, {"bar": ["first2", "second2"]}]}) -> ["first1", "second1"] search('foo | [0]', {"foo": [0, 1, 2]}) -> [0] 

Es gibt einen einfacheren Weg, dies zu tun jetzt.

http://github.com/akesterson/dpath-python

 $ easy_install dpath >>> dpath.util.search(YOUR_DICTIONARY, "morefoo/morebar") 

… erledigt. Oder wenn es Ihnen nicht geht, Ihre Ergebnisse wieder in eine Ansicht zu bringen (verschmolzenes Wörterbuch, das die Pfade behält), geben sie stattdessen:

 $ easy_install dpath >>> for (path, value) in dpath.util.search(YOUR_DICTIONARY, "morefoo/morebar", yielded=True) 

… und fertig. 'Value' wird in diesem Fall {'bacon': 'foobar'} halten.

Es gibt die neuere jsonpath-rw- Bibliothek, die eine JSONPATH- Syntax unterstützt, aber für python- Wörterbücher und Arrays , wie Sie es wünschten.

So wird dein erstes Beispiel:

 from jsonpath_rw import parse print( parse('$.morefoo.morebar').find(foo) ) 

Und der 2.:

 print( parse("$.morefoo[0].morebar.bacon").find(foo) ) 

PS: Eine alternative, einfachere Bibliothek, die auch Wörterbücher unterstützt, ist python-json-pointer mit einer mehr XPath-ähnlichen Syntax.

Mehr Arbeit müsste in die Frage gestellt werden, wie der XPath-ähnliche Selektor funktionieren würde. '/' Ist ein gültiger Wörterbuchschlüssel

 foo={'/':{'/':'eggs'},'//':'ham'} 

gehandhabt werden?

 foo.select("///") 

Wäre zweideutig.

Eine andere Alternative (neben der von jellybean vorgeschlagenen ) ist dies:

 def querydict(d, q): keys = q.split('/') nd = d for k in keys: if k == '': continue if k in nd: nd = nd[k] else: return None return nd foo = { 'spam':'eggs', 'morefoo': { 'bar':'soap', 'morebar': {'bacon' : 'foobar'} } } print querydict(foo, "/morefoo/morebar") 

Gibt es einen Grund für dich auf die Abfrage es so wie das XPath-Muster? Als der Kommentator zu Ihrer Frage vorgeschlagen, es nur ein Wörterbuch, so können Sie die Elemente in einer Nest Weise zugreifen. Auch wenn man bedenkt, dass die Daten in Form von JSON vorliegen, können Sie das easyjson-Modul verwenden, um es zu laden und auf die Elemente zuzugreifen.

Es gibt dieses Projekt JSONPATH , das versucht, den Leuten zu helfen, gegenüber zu tun, was du beabsichtigst zu tun (gegeben ein XPATH, wie man es leicht zugänglich über Pythonobjekte macht), was sinnvoller erscheint.

  • Scrapy, das eine Nullausgabe zurückgibt, wenn ein Element aus einer Tabelle mit xpath extrahiert wird
  • Python xml query erhalten übergeordnet
  • Wie kann ich diesen XPath-Ausdruck in BeautifulSoup übersetzen?
  • Python und libxml2: wie man in xml-Knoten mit XPATH iterieren kann
  • Welche reine Python-Bibliothek soll ich verwenden, um eine Website zu kratzen?
  • Sortieren von XML-Dateien
  • Wie passe ich den Inhalt eines Elements in XPath (lxml) an?
  • Wie finde ich XML-Elemente über XPath in Python in einer namenpace-agnostischen Weise?
  • Xpath funktioniert nicht mit dieser Website, überprüfen pls
  • Warum gibt mein Scrapy-Code ein leeres Array zurück?
  • Wie ordnungsgemäß verwenden Regeln, beschränken_xpaths zu crawlen und analysieren URLs mit scrapy?
  • Python ist die beste Programmiersprache der Welt.