django用模板解析xml

时间:2010-03-03 17:36:25

标签: xml django

我正在寻找创建一种动态方法来解析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 :(得分:0)

问题在于Django如何尝试评估上下文变量:

  1. 字典查找,
  2. 属性查找,
  3. list-index lookup,
  4. 函数调用。
  5. 首先尝试字典查找。您的XMLTree类实现了__getitem__方法,因此可以像字典一样访问它。问题是,如果请求不存在的密钥,则您的类不会引发KeyError。而是返回None

    在模板中{{ xml.Order(...) }}被评估为xml['Order']__getitem__('Order')执行返回None的self.node.attrib.get(key),这就是模板中没有显示任何内容的原因。

    所以:

    • __getitem__没有返回应该的内容(None而不是'Order')
    • KeyError未提出def __getitem__(self, key): out = self.node.attrib.get(key) if out is not None: return out else: raise KeyError

    我添加了一个简单的检查并修复了问题,因此模板会以正确的值呈现:

    {{1}}