2011-09-07 14 views
6

siguiente es el archivo XML: book.xml¿Cómo almacenar eficientemente este documento XML analizado en la base de datos MySQL usando Python?

<?xml version="1.0" ?> 
<!--Sample XML Document--> 
<bookstore> 
    <book _id="E7854"> 
     <title> 
      Sample XML Book 
     </title> 
     <author> 
      <name _id="AU363"> 
     <first> 
      Benjamin 
     </first> 

     <last> 
      Smith 
     </last> 
      </name> 
      <affiliation> 
     A 
      </affiliation> 
     </author> 
     <chapter number="1"> 
      <title> 
     First Chapter 
      </title> 
      <para> 
     B 
     <count> 
      783 
     </count> 
     . 
      </para> 
     </chapter> 
     <chapter number="3"> 
      <title> 
     Third Chapter 
      </title> 
      <para> 
     B 
     <count> 
      59 
     </count> 
     . 
      </para> 
     </chapter> 
    </book> 
    <book _id="C843"> 
     <title> 
      XML Master 
     </title> 
     <author> 
      <name _id="AU245"> 
     <first> 
      John 
     </first> 

     <last> 
      Doe 
     </last> 
      </name> 
      <affiliation> 
     C 
      </affiliation> 
     </author> 
     <chapter number="2"> 
      <title> 
     Second Chapter 
      </title> 
      <para> 
     K 
     <count> 
      54 
     </count> 
     . 
      </para> 
     </chapter> 
     <chapter number="3"> 
      <title> 
     Third Chapter 
      </title> 
      <para> 
     K 
     <count> 
      328 
     </count> 
     . 
      </para> 
     </chapter> 
     <chapter number="7"> 
      <title> 
     Seventh Chapter 
      </title> 
      <para> 
     K 
     <count> 
      265 
     </count> 
     . 
      </para> 
     </chapter> 
     <chapter number="9"> 
      <title> 
     Ninth Chapter 
      </title> 
      <para> 
     K 
     <count> 
      356 
     </count> 
     . 
      </para> 
     </chapter> 
    </book> 
</bookstore> 

siguiente es el código Python: book_dom.py

from xml.dom import minidom, Node 
import re, textwrap 

class SampleScanner: 
    def __init__(self, doc): 
     for child in doc.childNodes: 
      if child.nodeType == Node.ELEMENT_NODE and child.tagName == 'bookstore': 
       self.handleBookStore(child) 

    def gettext(self, nodelist): 
     retlist = [] 
     for node in nodelist: 
      if node.nodeType == Node.TEXT_NODE: 
       retlist.append(node.wholeText) 
      elif node.hasChildNodes: 
       retlist.append(self.gettext(node.childNodes)) 

     return re.sub('\s+', ' ', ''.join(retlist)) 

    def handleBookStore(self, node): 
     for child in node.childNodes: 
      if child.nodeType != Node.ELEMENT_NODE: 
       continue 
      if child.tagName == 'book': 
     self.handleBook(child) 

    def handleBook(self, node): 
     for child in node.childNodes: 
      if child.nodeType != Node.ELEMENT_NODE: 
       continue 
      if child.tagName == 'title': 
       print "Book title is:", self.gettext(child.childNodes) 
      if child.tagName == 'author': 
       self.handleAuthor(child) 
      if child.tagName == 'chapter': 
       self.handleChapter(child) 

    def handleAuthor(self, node): 
     for child in node.childNodes: 
      if child.nodeType != Node.ELEMENT_NODE: 
       continue 
      if child.tagName == 'name': 
       self.handleAuthorName(child) 
      elif child.tagName == 'affiliation': 
       print "Author affiliation:", self.gettext([child]) 

    def handleAuthorName(self, node): 
     surname = self.gettext(node.getElementsByTagName("last")) 
     givenname = self.gettext(node.getElementsByTagName("first")) 
     print "Author Name: %s, %s" % (surname, givenname) 

    def handleChapter(self, node): 
     print " *** Start of Chapter %s: %s" % (node.getAttribute('number'), 
      self.gettext(node.getElementsByTagName('title'))) 
     for child in node.childNodes: 
      if child.nodeType != Node.ELEMENT_NODE: 
       continue 
      if child.tagName == 'para': 
       self.handlePara(child) 

    def handlePara(self, node): 
     partext = self.gettext([node]) 
     partext = textwrap.fill(partext) 
     print partext 
     print 

doc = minidom.parse('book.xml') 
SampleScanner(doc) 

Salida: ~/$ pitón book_dom.py

Book ID : E7854 
Book title is: Sample XML Book 
Name ID : AU363 
Author Name: Smith , Benjamin 
Author affiliation: A 
*** Start of Chapter 1: First Chapter 
B 783 . 

*** Start of Chapter 3: Third Chapter 
B 59 . 

Book ID : C843 
Book title is: XML Master 
Name ID : AU245 
Author Name: Doe , John 
Author affiliation: C 
*** Start of Chapter 2: Second Chapter 
K 54 . 

*** Start of Chapter 3: Third Chapter 
K 328 . 

*** Start of Chapter 7: Seventh Chapter 
K 265 . 

*** Start of Chapter 9: Ninth Chapter 
K 356 . 

Mi objetivo es almacenar los libros en la tabla "Libros" y la información del autor en la tabla "Autores" (preservar el libro -> relación del autor) [MySQL DB].

**Book table :** 
id |title 
E7854 Sample XML Book 
.... 

**Chapter table :** 
book_id|chapter_number|title  |para 
E7854 1    First Chapter B 783 . 
E7854 3    Third Chapter B 59 . 
.... 

**Author table :** 
id |book_id |name   |Affiliation 
AU363 E7854  Smith Benjamin A 
.... 

¿Cómo hago para almacenar los datos en la base de datos si tengo unos cuantos miles de libros y autores (y capítulos)? Tengo problemas para identificar de forma única el conjunto de datos de cada libro/autor. Puedo usar los ID y pasarlos a las funciones para preservar la relación, pero no estoy seguro de si esa es la mejor manera de hacerlo. Cualquier puntero es muy apreciado.

p.s: Estoy trabajando en la parte SQL de la secuencia de comandos y la actualizaré una vez que la pruebe. Siéntase libre de publicar sus pensamientos, ejemplos de código. ¡Gracias!

+0

Awesome question. –

+0

Esta es una pregunta interesante, pero no estoy seguro de que la * pregunta * sea clara. ¿Está buscando orientación para el diseño de bases de datos relacionales, o quiere ayuda con el código para traducir su XML a su diseño de base de datos existente? – syrion

+0

Estoy buscando ayuda con el código de Python para realizar un seguimiento de cada registro único para almacenar en la base de datos. Incluso una lista o dict de Python ayudará: tengo dificultades para tratar de diferenciar cada registro a medida que analizo cada nodo. – ThinkCode

Respuesta

2

Según su comentario anterior, simplemente crearía una clase de libro, una clase de autor, una lista de autores y una clase de capítulo. Asigne los capítulos del libro a una lista de objetos del Capítulo en el Libro mismo. Mantenga el AuthorList como un dict de sus ID, apuntando a los objetos de autor reales. Use un miembro de datos del objeto Libro para contener la ID; puede proporcionar un método para sacar al autor del dict de AuthorList por conveniencia.

+0

Gracias por la sugerencia. No estoy muy versado en las clases de Python, todavía estoy aprendiendo. Definitivamente voy a probar tu enfoque. ¡Las funciones excesivas me confundieron con el manejo de datos! – ThinkCode

Cuestiones relacionadas