我正在寻找创建一种动态方法来解析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>
没有显示任何内容。我希望它能够实现我的目标。
谢谢!
答案 0 :(得分:0)
问题在于Django如何尝试评估上下文变量:
首先尝试字典查找。您的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}}