2010-03-03 8 views
1

Je cherche à créer une manière dynamique pour analyser les fichiers XML et les convertir en un autre format aussi facile que possible ..django analyse syntaxique xml avec le modèle

Voici mon fixture.xml

<Orders> 
     <Order number="" queue="true" getTax="true"> 
      <Customer> 
        <Email><![CDATA[[email protected]]]></Email> 
      </Customer> 
     </Order> 
</Orders> 

J'utilise le code suivant

try: 
    import xml.etree.cElementTree as ET 
except ImportError: 
    import xml.etree.ElementTree as ET 



class XMLTree(object): 
    def __init__(self, node): 
     self.nodes = {} 
     self.node = node 
     for n in node: 
      if len(n.getchildren()): 
       xmlnode = XMLTree(n) 
      else: 
       xmlnode = XMLNode(n) 
      if n.tag in self.nodes: 
       if isinstance(self.nodes[n.tag], (XMLTree, XMLNode)): 
        self.nodes[n.tag] = [self.nodes[n.tag], xmlnode] 
       else: 
        self.nodes[n.tag].append(xmlnode) 
      else: 
       self.nodes[n.tag] = xmlnode 

    def __unicode__(self): 
     return unicode(dict((k, str(v)) for k, v in self.nodes.iteritems())) 

    def __str__(self): 
     return unicode(self).encode('utf-8') 

    def __getattr__(self, attr): 
     return self.nodes[attr] 

    def __getitem__(self, key): 
     return self.node.attrib.get(key) 

    def __len__(self): 
     return len(self.nodes) 

    def items(self): 
     return self.nodes 

class XMLNode(object): 
    def __init__(self, node): 
     self.node = node 

    def __getitem__(self, key): 
     return self.node.attrib.get(key) 

    def __unicode__(self): 
     return self.node.text or '' 

    def __str__(self): 
     return unicode(self).encode('utf-8') 

    def __repr__(self): 
     return self.__unicode__() 

    def __len__(self): 
     return 1 


def order_taxcalc(request): 
    tree = ET.parse("/tmp/fixture.xml") 
    xml = XMLTree(tree.getroot()) 


    print "Email: ", xml.Order.Customer.Email 
    omxXML = render_to_string("endpoints/order.html", {'xml': xml}) 
    return HttpResponse(omxXML) 

maintenant, je reçois l'e-mail correct dans la console .. mais voici mon order.html dépouillé

<Email>{{xml.Order.Customer.Email}}</Email> 

Rien n'est affiché. J'espère que ça fait depuis avec ce que j'essaye de faire.

Merci!

Répondre

0

Le problème réside dans la façon dont Django tente d'évaluer les variables de contexte:

  1. consultation du dictionnaire,
  2. recherche d'attribut,
  3. list-index recherche,
  4. appel de fonction.

D'abord, une recherche de dictionnaire est essayée. Votre classe XMLTree implémente la méthode __getitem__, donc vous pouvez y accéder comme un dictionnaire. Le problème est que votre classe n'élève aucune KeyError si une clé non existante est demandée. Au lieu de cela, il renvoie None.

Dans le modèle {{ xml.Order(...) }} est évalué à xml['Order'], qui exécute __getitem__('Order') qui renvoie Aucun, ce qui explique pourquoi il n'y a rien affiché dans votre modèle.

Donc, soit:

  • self.node.attrib.get(key) ne retourne pas ce qui est devrait (aucun au lieu de 'Ordre')
  • __getitem__ ne soulève pas la KeyError.

J'ai ajouté un simple contrôle et il résout le problème, donc modèle obtient presté, valeur correcte:

def __getitem__(self, key): 
    out = self.node.attrib.get(key) 
    if out is not None: 
     return out 
    else: 
     raise KeyError