2010-09-24 18 views
7

Python elementTree parece inutilizable con espacios de nombres. ¿Cuáles son mis alternativas? BeautifulSoup es bastante basura con espacios de nombres también. No quiero quitarlos.Buen analizador XML de python para trabajar con documentos pesados ​​de espacio de nombres

Ejemplos de cómo una determinada biblioteca de python obtiene elementos de espacio de nombres y sus colecciones son todas +1.

Editar: ¿Podría proporcionar un código para tratar este caso de uso del mundo real utilizando la biblioteca que prefiera?

¿cómo usted va sobre conseguir cuerdas 'salto de línea', '2.6' y una lista [ 'PYTHON', 'XML', 'XML-NAMESPACES']

<?xml version="1.0" encoding="UTF-8"?> 
<zs:searchRetrieveResponse 
    xmlns="http://unilexicon.com/vocabularies/" 
    xmlns:zs="http://www.loc.gov/zing/srw/" 
    xmlns:dc="http://purl.org/dc/elements/1.1/" 
    xmlns:lom="http://ltsc.ieee.org/xsd/LOM"> 
    <zs:records> 
     <zs:record> 
      <zs:recordData> 
       <srw_dc:dc xmlns:srw_dc="info:srw/schema/1/dc-schema"> 
        <name>Line Break</name> 
        <dc:title>Processing XML namespaces using Python</dc:title> 
        <dc:description>How to get contents string from an element, 
         how to get a collection in a list...</dc:description> 
        <lom:metaMetadata> 
         <lom:identifier> 
          <lom:catalog>Python</lom:catalog> 
          <lom:entry>2.6</lom:entry> 
         </lom:identifier> 
        </lom:metaMetadata> 
        <lom:classification> 
         <lom:taxonPath> 
          <lom:taxon> 
           <lom:id>PYTHON</lom:id> 
          </lom:taxon> 
         </lom:taxonPath> 
        </lom:classification> 
        <lom:classification> 
         <lom:taxonPath> 
          <lom:taxon> 
           <lom:id>XML</lom:id> 
          </lom:taxon> 
         </lom:taxonPath> 
        </lom:classification> 
        <lom:classification> 
         <lom:taxonPath> 
          <lom:taxon> 
           <lom:id>XML-NAMESPACES</lom:id> 
          </lom:taxon> 
         </lom:taxonPath> 
        </lom:classification> 
       </srw_dc:dc> 
      </zs:recordData> 
     </zs:record> 
     <!-- ... more records ... --> 
    </zs:records> 
</zs:searchRetrieveResponse> 
+1

Me encanta la naturaleza de su meta MWe. –

+0

El uso de palabras clave relevantes en el código de ejemplo significa que más usuarios pueden encontrar la pregunta y las respuestas. –

Respuesta

12

lxml es consciente del espacio de nombres.

>>> from lxml import etree 
>>> et = etree.XML("""<root xmlns="foo" xmlns:stuff="bar"><bar><stuff:baz /></bar></root>""") 
>>> etree.tostring(et, encoding=str) # encoding=str only needed in Python 3, to avoid getting bytes 
'<root xmlns="foo" xmlns:stuff="bar"><bar><stuff:baz/></bar></root>' 
>>> et.xpath("f:bar", namespaces={"b":"bar", "f": "foo"}) 
[<Element {foo}bar at ...>] 

Editar: En el ejemplo:

from lxml import etree 

# remove the b prefix in Python 2 
# needed in python 3 because 
# "Unicode strings with encoding declaration are not supported." 
et = etree.XML(b"""...""") 

ns = { 
    'lom': 'http://ltsc.ieee.org/xsd/LOM', 
    'zs': 'http://www.loc.gov/zing/srw/', 
    'dc': 'http://purl.org/dc/elements/1.1/', 
    'voc': 'http://www.schooletc.co.uk/vocabularies/', 
    'srw_dc': 'info:srw/schema/1/dc-schema' 
} 

# according to docs, .xpath returns always lists when querying for elements 
# .find returns one element, but only supports a subset of XPath 
record = et.xpath("zs:records/zs:record", namespaces=ns)[0] 
# in this example, we know there's only one record 
# but else, you should apply the following to all elements the above returns 

name = record.xpath("//voc:name", namespaces=ns)[0].text 
print("name:", name) 

lom_entry = record.xpath("zs:recordData/srw_dc:dc/" 
         "lom:metaMetadata/lom:identifier/" 
         "lom:entry", 
         namespaces=ns)[0].text 

print('lom_entry:', lom_entry) 

lom_ids = [id.text for id in 
      record.xpath("zs:recordData/srw_dc:dc/" 
         "lom:classification/lom:taxonPath/" 
         "lom:taxon/lom:id", 
         namespaces=ns)] 

print("lom_ids:", lom_ids) 

Salida:

name: Frank Malina 
lom_entry: 2.6 
lom_ids: ['PYTHON', 'XML', 'XML-NAMESPACES'] 
+2

+1 lxml es la única herramienta/paquete de python que necesitará para tareas relacionadas con xml/xslt/xpath – snapshoe

+0

Editar: ¿Cómo codificaría el ejemplo proporcionado? La falta de recetas en la web para este tipo de trabajo lxml es espantosa. Por el momento, procedí eliminando los espacios de nombres y atravesando con BeautifulSoup. Esto no es óptimo en varios niveles. –

+0

@Frank Malina: XPath no es específico de lxml, hay algunos recursos utilizables en XPath en la web. Pero haré una puñalada ... – delnan

0

libxml (http://xmlsoft.org/) mejor, más rápido lib de análisis XML. Hay implementación para python.

+4

lxml de codespeak wraps y utiliza libxml – snapshoe

Cuestiones relacionadas