django разбирает xml с шаблоном - PullRequest
1 голос
/ 03 марта 2010

Я хочу создать динамический способ для анализа XML-файлов и преобразования их в другой формат как можно проще ..

Вот мой fixture.xml

<Orders>
      <Order number="" queue="true" getTax="true">
            <Customer>
                  <Email><![CDATA[mike@domain.com]]></Email>
            </Customer>
      </Order>
</Orders>

Я использую следующий код

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)

Теперь я получаю правильное письмо в консоли ... но вот мой order.html урезанный

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

Ничего не отображается. Я надеюсь, что это делает с тем, что я пытаюсь сделать.

Спасибо!

1 Ответ

0 голосов
/ 07 февраля 2012

Проблема заключается в том, как Django пытается оценить контекстные переменные:

  1. поиск по словарю,
  2. поиск атрибутов,
  3. просмотр списка индексов,
  4. вызов функции.

Сначала выполняется поиск по словарю. Ваш класс XMLTree реализует метод __getitem__, поэтому к нему можно обращаться как к словарю. Проблема в том, что ваш класс не поднимает KeyError, если запрашивается несуществующий ключ. Вместо этого он возвращает None.

В шаблоне {{ xml.Order(...) }} оценивается как xml['Order'], который выполняет __getitem__('Order'), который возвращает None, поэтому в вашем шаблоне ничего не отображается.

Так что либо:

  • self.node.attrib.get(key) не возвращает то, что должно (Нет вместо 'Order')
  • __getitem__ не поднимает KeyError.

Я добавил простую проверку, и она устраняет проблему, поэтому шаблон отображается с правильным значением:

def __getitem__(self, key):
    out = self.node.attrib.get(key)
    if out is not None:
        return out
    else:
        raise KeyError
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...