XML ORMZ数据库库将XML集合映射到Python模型对象

xml-ormz的Python项目详细描述


XML或MZ

作者:姜子健

2019年8月29日:alpha版本。

xml ormz是一个orm(对象关系映射)库,用于将一组关系xml文件映射到本机python对象。它能够将xml文档树解析为层次类model对象。在将XML文档树解析为对象时,它将检查属性“fieldtype;value content;amount of elements;numbers;regular expressions等。这些验证规则都可以由用户直观地定义。作为另一个重要特性,object relationships可以通过在xml ormz中使用finders来构建,finder是一个用户自定义的可调用对象,用于递归遍历树以在两个或多个对象之间构建引用。最后,您将得到一个经过验证的映射关系python对象模型(不考虑无效的属性类型或值;缺少属性;元素数量错误;缺少关系;无效的模式…)。在我的数据处理哲学中(xml格式是一种高度复杂的层次数据),所有的输入数据在后续的任何处理之前都要经过验证,不能让恶性传播,而xml orm则要做到这一点。

一。安装

下面的命令将完成这个技巧,如果您想要使用颜色进行日志记录,则可以选择安装coloredlogs

pip install xml-ormz

2.示例

它总是说一个例子超出了任何文档的范围,所以让我们来看看。

以下是项目层次结构:

+ProjectFolder/contacts.xmladdresses.xmlmodel.pyfinder.pyhello.py# main entry

假设我们有两个xml文件。

<!-- contacts.xml --><Contacts><Personname="Alice"address="Wonderland Street No.231"><Email>513754619@mail.com</Email><Phonenumber="513754619"/><Phonenumber="611953242"/></Person><Personname="Rabbit"address="Moon Street No.1"><Email>645118456@gmail.com</Email><Phonenumber="645118456"/></Person></Contacts>
<!-- addresses.xml --><Addresses><Apartmentlocation="Wonderland Street No.231"year="1898"owner="Queen of Hearts"/><Apartmentlocation="Moon Street No.1"year="2"area="401"/></Addresses>
  1. 我们为类模型定义创建model.py
# model.pyfromxo.ormimportModel,Optional,StringField,FloatField,IntegerField,ForeignKeyFieldclassContacts(Model):classPerson(Model):name=StringField(re=r"(Alice|Rabbit|John)")# regular expression validationaddress=StringField()classEmail(Model):__count__=1# every person must have one and only one emailpass# email address is in email.text and text is not a attributeclassPhone(Model):__count__=(1,)# every person must have at least one phonenumber=IntegerField(primary_key=True)classAddresses(Model):classApartment(Model):location=StringField(primary_key=True)year=IntegerField()owner=Optional(StringField())# owner attribute can be none, not required (without it will raise an error)# forget to define `area` field here # when you run the program it will warn you that:# 2019-08-29 15:21:40 X root[7828] WARNING Try to assign extra attribute 'area' to undefined field of 'Addresses.Apartment', drop it.# So your `area` attribute in addresses.xml will never appear in this object.
  1. 创建程序的主条目hello.py
# hello.pyfrommodelimportContacts,Addressesfromxo.crawlerimportXmlMapperaddress_map=XmlMapper("./addresses.xml",Addresses).parse()contact_map=XmlMapper("./contacts.xml",Contacts).parse()
Result:address_map-+'/Addresses':<classAddresses>-'childApartment':[<classAddresses.Apartment>]-'childHouse':[<classAddresses.House>]-'text':''+'/Addresses/Apartment[1]':<classAddresses.Apartment>-'location':'Wonderland Street No.231'-'owner':'Queen of Hearts'-'parentAddresses':<classAddresses>-'year':1898+'/Addresses/Apartment[2]':<classAddresses.Apartment>-'location':'Moon Street No.1'-'parentAddresses':<classAddresses>-'year':2contact_map-+'/Contacts':<classContacts>+'/Contacts/Person[1]':<classContacts.Person>+'/Contacts/Person[1]/Email':<classContacts.Person.Email>-'parentPerson':<classContacts.Person>-'text':'513754619@mail.com'+'/Contacts/Person[1]/Phone[1]':<classContacts.Person.Phone>+'/Contacts/Person[1]/Phone[2]':<classContacts.Person.Phone>+'/Contacts/Person[2]':<classContacts.Person>+'/Contacts/Person[2]/Email':<classContacts.Person.Email>+'/Contacts/Person[2]/Phone':<classContacts.Person.Phone>...

如果您注意到我们的所有xml文件都已被解析为python本地对象,并且所有属性都已验证。现在是我们进一步探索对象关系的时候了。

  1. 我们将附加字段添加到已经定义的model.py
# model.py+fromxo.ormimportForeignKeyField...classPerson(Model):name=StringField(re=r"(Alice|Rabbit|John)")# regular expression validationaddress=StringField()+apartment=ForeignKeyField('Addresses.Apartment')...
  1. finder.py
  2. 中创建查找程序
#finder.pyfrommodelimportAddresses,ContactsclassFinder(object):def__init__(self,orm_list):# Here the parameter `orm_list` is assigned by xml-ormz, `orm_list = [ contact_map, addresses_map ]`self.addresses=[mforminorm_listif"/Addresses"inm][0]def__call__(self,person):# Here we find `address` using `person` object passed to ustry:found=next(apartmentforapartmentinself.addressesifapartment.location==person.address)exceptStopIteration:returnNone# if we not foundContacts.Person.getField("apartment").finder=Finder
  1. 修改hello.py并查看结果。
# hello.pyfrommodelimportContacts,Addressesfromxo.crawlerimportXmlMapper,XmlLinker+importfinder# don't forget to import the finders we wrote !address_map=XmlMapper("./addresses.xml",Addresses).parse()contact_map=XmlMapper("./contacts.xml",Contacts).parse()+linker=XmlLinker([address_map,contact_map],[Addresses,Contacts])+linker.link()# let's see if Person's apartment is found?+print(contact_map["/Contacts/Person[1]"].apartment)#Result: <class Addresses.Apartment>: {'location': 'Wonderland Street No.231', 'year': 1898, 'owner': 'Queen of Hearts', 'parentAddresses': <class Addresses>}

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
swing Java按钮/网格布局   java列出Google日历中的所有事件   java无效:单击API publisher test按钮后连接到后端时出错   带有内部赋值的java While循环导致checkstyle错误   java为什么trimToSize/ensureCapacity方法提供“公共”级访问?   文件输出流的java问题   ListIterator和并发修改异常的java问题   java如何使用两个URL映射   无法识别使用“./../”构造的字符串java相对路径,为什么?   首次写入remotelyclosedsocket不会触发异常,对吗?JAVA   java OneDrive REST API为文件上载提供了400个无效谓词   Java泛型、集合接口和对象类的问题   OpenSSL Java安全提供程序   jmeter java运行jmx禁用操作