2014-06-20 5 views
0

J'ai une grande forme de fichier bz2 wikipedia contiennent une image de leurs articles au format xml.Créer un index d'un fichier XML volumineux

Obtenir le texte à partir de la décharge n'est pas difficile. J'utilise le code suivant pour analyser le fichier XML. Je veux savoir s'il existe un moyen d'ouvrir le fichier orignal bz2 ou xml une fois qu'il a été lu, et l'indexer, de sorte que je puisse associer différentes lignes (par exemple, l'article pour un "Barack Obama") avec cet index, et alors quand cette ligne est nécessaire, je peux y aller directement.

Une possibilité consiste à diviser le fichier bz2 ou xml en fragments plus petits, puis à indexer ces fragments. Est-ce que quelqu'un a des idées sur la façon de trouver des lignes spécifiques le plus rapidement possible?

import bz2 
try: 
    from lxml import etree 
except ImportError: 
    import xml.etree.ElementTree as etree 
import re 


def _get_namespace(tag): 
    namespace = re.match("^{(.*?)}", tag).group(1) 
    if not namespace.startswith("http://www.mediawiki.org/xml/export-"): 
     raise ValueError("%s not recognized as MediaWiki database dump" 
         % namespace) 
    return namespace 

def extract_pages(f): 
    elems = (elem for _, elem in etree.iterparse(f, events=["end"])) 
    elem = next(elems) 

    namespace = _get_namespace(elem.tag) 
    ns_mapping = {"ns": namespace} 
    page_tag = "{%(ns)s}page" % ns_mapping 
    text_path = "./{%(ns)s}revision/{%(ns)s}text" % ns_mapping 
    id_path = "./{%(ns)s}id" % ns_mapping 
    title_path = "./{%(ns)s}title" % ns_mapping 
    for elem in elems: 
     if elem.tag == page_tag: 
      text = elem.find(text_path).text 
      if text is None: 
       continue 
      yield (int(elem.find(id_path).text), 
        elem.find(title_path).text, 
        text) 
      elem.clear() 
      if hasattr(elem, "getprevious"): 
       while elem.getprevious() is not None: 
        del elem.getparent()[0] 

if __name__ == "__main__": 
    dictionary={} 
    f = bz2.BZ2File("simplewiki.xml.bz2", 'rb') 

    for pageid, title, text in extract_pages(f): 
     print pageid 

Répondre

0

Un fichier XML n'est pas une base de données ... l'utiliser en tant que telle est inévitablement une sorte d'abus et d'essayer d'ajouter des fonctionnalités de base de données comme un « index » au-dessus de celui-ci ne fera qu'empirer les choses à mon humble avis. De plus, le contenu d'un fichier bz2 n'est pas disponible. Si vous avez besoin d'une base de données, importez le code XML dans une base de données.

Pour la plupart des tâches impliquant des vidages XML, mediawiki-utilities est l'option la plus rapide. Juste à titre d'exemple, pour obtenir le vous pouvez faire quelque chose de similaire à l'exemple du texte de [[Barack Obama]] dans la documentation, en supposant que vous avez téléchargé la décharge de la version actuelle:

from mw.xml_dump import Iterator 

# Construct dump file iterator 
dump = Iterator.from_file(open("example/dump.xml")) 

# Iterate through pages 
for page in dump: 
    if page.title == "Barack Obama": continue 
    # Iterate through a page's revisions 
    for revision in page: 

     print(revision.text) 
+0

Eh? Une base de données XQuery peut absolument/va indexer un fichier XML en tant que base de données pour des recherches très efficaces. –

+0

@CharlesDuffy, intéressant, semble que vous devriez poster votre suggestion comme réponse. :) – Nemo

1

L'outil pour faire très XQuery est une recherche efficace par le biais de XML indexé - un langage pour lequel plusieurs bases de données indexées à grande vitesse sont disponibles. Des liaisons Python sont disponibles, vous pouvez donc exécuter une requête XQuery à partir de votre logiciel Python, mais vous voudrez écrire la requête elle-même dans XQuery, pas Python. Comme les bases de données SQL, les bases de données XQuery disposent d'optimiseurs de requêtes, mais la manière dont vous écrivez votre requête dépend encore de l'efficacité de l'utilisation des index (vous pouvez contrôler l'indexation par rapport à l'indexation uniquement index de texte avec stemming, et beaucoup d'endroits entre).

Si vous voulez une base de données Open Source XQuery avec un bon support de visualisation pour vous aider à écrire et déboguer votre code, BaseX peut être un bon point de départ; il a une interface utilisateur géniale, et reste très proche de la pointe de la spécification du langage, ajoutant constamment de nouvelles fonctionnalités telles qu'elles sont proposées par le groupe de travail W3C contrôlant l'évolution de XQuery. eXist est une autre base de données XQuery open-source bien entretenue, alors que MarkLogic fait probablement partie des implémentations XQuery commerciales les plus respectées.

Voir the list of available clients for BaseX, si vous voulez être en mesure d'exécuter vos requêtes depuis Python.

Voir également the detailed documentation on indexes in BaseX, pour être sûr que vous écrivez vos requêtes pour en tirer parti (et créer les index dont vous avez besoin).

Questions connexes