我有一组使用eulxml.xmlmap.XmlObject
创建的python对象(我使用此方法主要是因为我正在使用eXistDB服务器而eulxml提供了一个非常简单的映射功能)。我能够成功查询我的eXistDB并将xquery结果集加载到我创建的一些python对象中。我的问题是,当我将这些对象传递给Web服务器(使用Angular作为前端)时,我希望能够将这些对象写为JSON。
我尝试过使用jsonpickle,但似乎eulxml正在做一些延迟加载魔术。标准调用jsonpickle将我的对象序列化为json给了我这个结果:
python代码:
jsonpickle.encode(myObject)
结果:
"py/object": "models.alcalaPage.AlcalaPage", "context":
{"namespaces":
{"exist": "http://exist.sourceforge.net/NS/exist"}
},
"node": {
"py/object": "lxml.etree._Element",
"py/seq": [
{"py/object": "lxml.etree._Comment", "py/seq": []},
{"py/object": "lxml.etree._Element", "py/seq": []},
...
]
}...
它似乎只输出属性的类型而不是属性本身的值。如果我改变我的jsonpickle代码来设置unpickable = False,我得到的只是一组空的json(意味着结构就是正确数量的花括号和括号,但实际上没有数据.json输出是只是花括号和括号)。
我想也许,如果我试图访问字段中的值,然后输出可能有用的json(至少对于我访问的字段)但没有运气。我得到了与上述相同的结果(是的,我已经仔细检查过对象本身是否存在数据)。
我现在有点不知所措。我可以迁移到像BeautifulSoup这样的东西,但这意味着要编写更多的代码(eulxml让我只需指定xpath到我希望用bing填充我的属性的值,我就完成了)。 jsonpickle有什么我想念的吗?或者我应该看看另一个json包吗?或者我可能比我需要的更困难,并且还有其他方法可以使用python查询eXistDB,然后将信息发送到使用Angular构建的前端应用程序。我愿意接受建议。
我将在下面提供我的代码示例(我不会包含所有代码,因为我正在使用的对象可能超过10个):
使用eulxml的示例对象代码:
import jsonpickle
from eulxml.xmlmap import XmlObject
class AlcalaBase(XmlObject):
def to_xml(self):
return self.serializeDocument(pretty=True)
def to_json(self):
return jsonpickle.encode(self)
from eulxml import xmlmap
from models.alcalaBase import AlcalaBase
class AlcalaPage(AlcalaBase):
ROOT_NAME = 'page'
id = xmlmap.StringField('pageID')
archive_page_number = xmlmap.StringField('archivistsPageNumber')
year = xmlmap.IntegerField('content/@yearID')
答案 0 :(得分:0)
我能够找出问题(某种程度上)。所以我在这里发帖,以防其他人遇到同样的问题。
问题似乎是属性未添加到 dict ,因此在json过程中不会输出实际值。我在我的基类中编写了to_json()
方法,以便输出适当的对象。注意:虽然我试图尽可能保持通用,但它有点特定于我的数据结构(因为我知道在给定的场景中会发生什么,因为我处理静态数据,我不会这样做必须"未来证明"解决方案。任何采用此代码的人都应该根据他们给定的场景进行调整。
from eulxml import xmlmap
import inspect
import lxml
import json as JSON
class AlcalaBase(xmlmap.XmlObject):
def to_json(self, skipBegin=False):
json = list()
if not skipBegin:
json.append('{')
json.append(str.format('"{0}": {{', self.ROOT_NAME))
for attr, value in inspect.getmembers(self):
if (attr.find("_") == -1
and attr.find("serialize") == -1
and attr.find("context") == -1
and attr.find("node") == -1
and attr.find("schema") == -1):
if type(value) is xmlmap.fields.NodeList:
if len(value) > 0:
json.append(str.format('"{0}": [', attr))
for v in value:
json.append(v.to_json())
json.append(",")
json = json[:-1]
json.append("]")
else:
json.append(str.format('"{0}": null', attr))
elif (type(value) is xmlmap.fields.StringField
or type(value) is str
or type(value) is lxml.etree._ElementUnicodeResult):
value = JSON.dumps(value)
json.append(str.format('"{0}": {1}', attr, value))
elif (type(value) is xmlmap.fields.IntegerField
or type(value) is int
or type(value) is float):
json.append(str.format('"{0}": {1}', attr, value))
elif value is None:
json.append(str.format('"{0}": null', attr))
elif type(value) is list:
if len(value) > 0:
json.append(str.format('"{0}": [', attr))
for x in value:
json.append(x)
json.append(",")
json = json[:-1]
json.append("]")
else:
json.append(str.format('"{0}": null', attr))
else:
json.append(value.to_json(skipBegin=True))
json.append(",")
json = json[:-1]
if not skipBegin:
json.append('}')
json.append('}')
return ''.join(json)
从此类继承的任何内容都可以序列化为json。这也假设所有对象集合都继承自这个基类(在我的特定模型中,这是真的,因此它不是问题)。
答案 1 :(得分:0)
是的,jsonpickle调用 dict 方法以使其起作用,您可以在元类中使用以下内容:
No package found with specified pattern: D:\a\r1\a\**\*.zip
因此 dict 方法将直接返回字段的值