我正在使用suds来使用wsdl从第三方请求数据。我现在只保存一些返回的数据,但是我正在为我得到的数据付费,所以我想保留所有数据。我已经决定保存这些数据的最佳方法是将原始xml响应捕获到数据库字段中,以备将来使用,如果我决定要开始使用数据的不同部分,并在发生差异时作为文件跟踪。
所以我有两个问题:
是否有一种简单的方法可以从suds.client对象输出原始接收的xml?在我搜索到这个问题的答案时,我已经了解到这可以通过日志记录来完成,但我希望不必将日志中的信息反馈到数据库字段中。我也查看了MessagePlugin.recieved()钩子,但是在解析之后无法弄清楚如何访问这些信息,只是我可以覆盖该函数并且在解析时可以访问原始xml(这是在我决定它是否真的值得保存之前。我还研究了retxml选项,但我也想使用解析版本并进行两次单独调用,一次作为retxml,另一次解析将花费我两次。我希望在suds客户端中内置一个简单的函数(比如response.as_xml()或同样简单的东西),但还没有找到类似的东西。我头脑中冒泡的选项可能是使用.received()插件钩子扩展客户端对象,该钩子在解析之前将xml保存为对象参数,稍后将被引用...但执行此类似乎有点我现在很难接受,而且我很难相信肥皂水的客户不仅仅是已经把它建在某个地方,所以我想我先问一下。
我的问题的另一部分是:什么类型的django模型字段最适合处理最多约100 kb的文本数据作为原始xml?我打算简单地使用一个简单的CharField和一个愚蠢的max_length,但这感觉不对。
提前致谢。
答案 0 :(得分:7)
我通过在客户端初始化时使用标志retxml解决了这个问题:
client = Client(settings.WSDL_ADDRESS, retxml=True)
raw_reply = client.service.PersonSearch(soapified_search_object)
然后我能够将raw_reply作为原始xml保存到django models.TextField()中 然后注入原始xml以获得suds解析结果,而不必重新提交我的搜索lika所以:
parsed_result = client.service.PersonSearch(__inject={'reply': raw_reply})
我想如果我想从原始回复中删除suds信封的东西我可以使用python xml库来进一步使用回复,但是因为我现有的代码已经从suds客户端获取了我想要的信息结果我刚刚用过它。
希望这有助于其他人。
答案 1 :(得分:4)
我已经使用了kyrayzk解决方案一段时间了,但总是发现它有点hackish,因为我必须创建一个单独的虚拟客户端,只是为了我需要处理原始XML时。
所以我通过.last_received()
重新实现了.last_sent()
和MessagePlugin
方法(在冥想(错误地)中删除了suds-jurko 0.4.1)。
希望它可以帮到某人:
class MyPlugin(MessagePlugin):
def __init__(self):
self.last_sent_raw = None
self.last_received_raw = None
def sending(self, context):
self.last_sent_raw = str(context.envelope)
def received(self, context):
self.last_received_raw = str(context.reply)
用法:
plugin = MyPlugin()
client = Client(TRTH_WSDL_URL, plugins=[plugin])
client.service.SendSomeRequest()
print plugin.last_sent_raw
print plugin.last_received_raw
另外,如果你想要一个很好的缩进XML,试试这个:
from lxml import etree
def xmlpprint(xml):
return etree.tostring(etree.fromstring(xml), pretty_print=True)