今天給大家介紹一個(gè)用于處理xml的開源庫(kù)xml_models2,它主要能用來對(duì)xml文件進(jìn)行解析驳规。這個(gè)庫(kù)建立在lxml
之上,相比python自帶的xmlElementTree
恼五、lxml
等比較底層
的xml處理方式(lxml其實(shí)還行)镰矿,它充分利用了python元類的自示恫尽(元編程)特性罢屈,允許用戶根據(jù)相應(yīng)xml的結(jié)構(gòu)定義自己的model,在model的每個(gè)字段中指定對(duì)應(yīng)的xpath篇亭,利用lxml的xml處理功能將xml中對(duì)應(yīng)路徑的節(jié)點(diǎn)和內(nèi)容提取出來缠捌。與其說這是一個(gè)xml處理,更不如說它是一個(gè)輕量級(jí)的處理xml數(shù)據(jù)的ORM译蒂,只不過并沒有與數(shù)據(jù)庫(kù)打交道而已曼月。
如引言里面描述的那樣,xml_models2能夠通過自定義model來序列化
xml柔昼,獲取自己感興趣的節(jié)點(diǎn)的內(nèi)容哑芹。假如我們有如下一個(gè)xml:
<Person id="112">
<firstName>Chris</firstName>
<lastName>Tarttelin</lastName>
<occupation>Code Geek</occupation>
<website>http://www.pyruby.com</website>
<contact-info>
<contact type="telephone">
<info>(555) 555-5555</info>
<description>Cell phone, but no calls during work hours</description>
</contact>
<contact type="email">
<info>me@here.net</info>
<description>Where possible, contact me by email</description>
</contact>
<contact type="telephone">
<info>1-800-555-5555</info>
<description>Toll free work number for during office hours.</description>
</contact>
</contact-info>
</Person>
為了獲取相應(yīng)的數(shù)據(jù),我們就可以定義如下的model:
class Person(Model):
id = IntField(xpath="/Person/@id")
firstName = CharField(xpath="/Person/firstName")
lastName = CharField(xpath="/Person/lastName")
contacts = CollectionField(ContactInfo, order_by="contact_type", xpath="Person/contact-info/contact")
class ContactInfo(Model):
contact_type = CharField(xpath="/contact/@type")
info = CharField(xpath="/contact/info")
description = CharField(xpath="/contact/description", default="No description supplied")
Person和ContactInfo model繼承自積累xml_models.Model捕透,IntField聪姿,CharField,CollectionField等字段類型都是xml_models提供的字段類型乙嘀,相信用過像比如SQLAlchemy或者Django ORM的童鞋應(yīng)該不會(huì)陌生末购,只不過這里在使用這些字段的時(shí)候指定的值是一些xpath的值用來指定xml文件中相應(yīng)節(jié)點(diǎn)的路徑。定義好model之后乒躺,只要簡(jiǎn)單調(diào)用就能取到我們想要的數(shù)據(jù):
>>> person = Person(xml_str)
>>> person.contacts[0].info
me@here.com
在解析xml的時(shí)候招盲,嵌套重復(fù)有規(guī)則的xml數(shù)據(jù)可能會(huì)經(jīng)常會(huì)用到CollectionField
,除了像上面定義model的方式指定集合嘉冒,也能夠直接在model里面指定collection_node
:
class SomeModel(Model):
fieldA = CharField(xpath="/some/node")
collection_node = 'collection'
在這個(gè)庫(kù)里面還封裝了requests的一些基本功能曹货,這樣允許我們直接通過自定義的model里面發(fā)起http請(qǐng)求從提供的api獲取數(shù)據(jù):
data = SomeModel.objects.filter_custom(url_address_xxx).get()
獲取直接能夠通過rest api查詢查詢一些數(shù)據(jù):
class Person(xml_models.Model:
...
finders = { (firstName, lastName): "http://person/firstName/%s/lastName/%s",
(id,): "http:xxxx//person/%s"}
>>> people = Person.objects.filter(firstName='Chris', lastName='Tarttelin')
>>> people.count()
1
>>> person = Person.objects.get(id=123)
>>> person.firstName
Chris
除了如上所示提到的這些,xml_models2還有一些比較好玩的功能:
to_xml()
: 將xml序列化之后讳推,我們可能會(huì)做一些更改顶籽,更改之后調(diào)用這個(gè)api能夠生成包含更改內(nèi)容的xml;甚至能夠先定義model银觅,實(shí)例化自己的model實(shí)力然后生成xml礼饱。
validate_on_load()
: 在model中這個(gè)方法一個(gè)很好的“鉤子”,方便我們?cè)谛蛄谢臅r(shí)候進(jìn)行一些自定義的驗(yàn)證究驴。
blablablanla...
這個(gè)庫(kù)并沒有出來多久镊绪,是在另外一個(gè)開源庫(kù)xml_models上面fork而來,對(duì)大部分的代碼進(jìn)行了重構(gòu)洒忧,特別是元類Model/ModelBase
那塊蝴韭。另外項(xiàng)目的文檔,代碼注釋熙侍,單元測(cè)試都很完整榄鉴,非常鼓勵(lì)有興趣的童鞋可以關(guān)注一下履磨。
差不多就給大家介紹到這里,更多的內(nèi)容大家可以查看庫(kù)的文檔和github主頁(yè)庆尘。感興趣的同學(xué)可以試用一下剃诅,有什么問題可以去主頁(yè)上提issue或者pr。
這篇文章大部分部分的內(nèi)容都是從文檔搬來的驶忌,稍稍加了些自己的一些理解加以豐富矛辕,方便大家開始使用。