无法在 lxml.objectify 中设置 children 的值
Can't set children's values in lxml.objectify
我正在尝试使用使用 XML 的 restful 界面。我已将 XML 库的选择范围缩小到两个。
根据文档,lxml.objectify 似乎是我的首选,但我正在努力。
Xmltodict 似乎产生了更多的输入,并且可能不那么 pythonic 但我似乎能够取得更大的进展。
我有一个用两者制作的例子。 Xmltodict 正在工作,但使用 xml.objectify 我似乎无法弄清楚如何 access/change 凭证的子元素。我的假设是我可以使用点符号来获取用户名和密码,但我没有成功。
一、xmltodict代码:
from requests import post
import xmltodict
import pprint
pp=pprint.PrettyPrinter(indent=2)
req = '''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<HTNGHeader xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://htng.org/1.1/Header/">
<From>
<Credential>
<password>PASSWORD</password>
<userName>UNAME</userName>
</Credential>
<systemId>2</systemId>
</From>
<To>
<systemId>2178</systemId>
</To>
</HTNGHeader>
</soap:Header>
<soap:Body />
</soap:Envelope>
'''
pwd = 'password'
uname = 'username'
url = 'https://url.com'
soap = xmltodict.parse(req)
soap['soap:Envelope']['soap:Header']['HTNGHeader']['From']['Credential']['password'] = pwd
soap['soap:Envelope']['soap:Header']['HTNGHeader']['From']['Credential']['userName'] = uname
soap_post = xmltodict.unparse(soap)
res = post(url, data=soap_post)
res_dict = xmltodict.parse(res.text)
pp.pprint(res_dict)
现在,lxml.objectify.
from requests import post
from lxml import etree, objectify
import pprint
pp=pprint.PrettyPrinter(indent=2)
req = '''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<HTNGHeader xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://htng.org/1.1/Header/">
<From>
<Credential>
<password>PASSWORD</password>
<userName>UNAME</userName>
</Credential>
<systemId>2</systemId>
</From>
<To>
<systemId>2178</systemId>
</To>
</HTNGHeader>
</soap:Header>
<soap:Body />
</soap:Envelope>
'''
request_doc = req.encode('utf-8')
pwd = 'password'
uname = 'username'
url = 'https://url.com
soap = objectify.fromstring(request_doc)
#here is my problem
soap.Header.HTNGHeader.From.Credential.userName = uname
soap.Header.HTNGHeader.From.Credential.password = pwd
soap_post = etree.tostring(soap)
url = 'https://connect.channelrush.net/reservationreceive/pickup?providerId=2'
res = post(url, data=soap_post)
res_obj = objectify.fromstring(res.text.encode('utf-8'))
pp.pprint(res.text)
使用 lxml.objectify 我得到以下异常:
File "f:\Dropbox\pms\channel_rush_interface_objectify.py", line 36, in <module>
soap.Header.HTNGHeader.From.Credential.userName = uname
File "c:\Python34\Lib\site-packages\lxml\objectify.pyd", line 230, in lxml.objectify.ObjectifiedElement.__getattr__ (src\lxml\objectify.c:4443)
File "c:\Python34\Lib\site-packages\lxml\objectify.pyd", line 451, in lxml.objectify._lookupChildOrRaise (src\lxml\objectify.c:7228)
builtins.AttributeError: no such child: {http://schemas.xmlsoap.org/soap/envelope/}HTNGHeader
任何人都可以指出如何让 lxml.objectify 工作吗?我应该坚持使用 xmltodict 吗?
来自lxml.objectify documentation:
During tag lookups, namespaces are handled mostly behind the scenes. If you access a child of an Element without specifying a namespace, the lookup will use the namespace of the parent. ... To access an element in a different namespace than its parent, you can use getattr() ...
For convenience, there is also a quick way through item access. [examples removed]
对于你的情况,尝试:
soap.Header["{http://htng.org/1.1/Header/}HTNGHeader"].From.Credential.userName = uname
soap.Header["{http://htng.org/1.1/Header/}HTNGHeader"].From.Credential.password = pwd
我正在尝试使用使用 XML 的 restful 界面。我已将 XML 库的选择范围缩小到两个。
根据文档,lxml.objectify 似乎是我的首选,但我正在努力。
Xmltodict 似乎产生了更多的输入,并且可能不那么 pythonic 但我似乎能够取得更大的进展。
我有一个用两者制作的例子。 Xmltodict 正在工作,但使用 xml.objectify 我似乎无法弄清楚如何 access/change 凭证的子元素。我的假设是我可以使用点符号来获取用户名和密码,但我没有成功。
一、xmltodict代码:
from requests import post
import xmltodict
import pprint
pp=pprint.PrettyPrinter(indent=2)
req = '''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<HTNGHeader xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://htng.org/1.1/Header/">
<From>
<Credential>
<password>PASSWORD</password>
<userName>UNAME</userName>
</Credential>
<systemId>2</systemId>
</From>
<To>
<systemId>2178</systemId>
</To>
</HTNGHeader>
</soap:Header>
<soap:Body />
</soap:Envelope>
'''
pwd = 'password'
uname = 'username'
url = 'https://url.com'
soap = xmltodict.parse(req)
soap['soap:Envelope']['soap:Header']['HTNGHeader']['From']['Credential']['password'] = pwd
soap['soap:Envelope']['soap:Header']['HTNGHeader']['From']['Credential']['userName'] = uname
soap_post = xmltodict.unparse(soap)
res = post(url, data=soap_post)
res_dict = xmltodict.parse(res.text)
pp.pprint(res_dict)
现在,lxml.objectify.
from requests import post
from lxml import etree, objectify
import pprint
pp=pprint.PrettyPrinter(indent=2)
req = '''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<HTNGHeader xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://htng.org/1.1/Header/">
<From>
<Credential>
<password>PASSWORD</password>
<userName>UNAME</userName>
</Credential>
<systemId>2</systemId>
</From>
<To>
<systemId>2178</systemId>
</To>
</HTNGHeader>
</soap:Header>
<soap:Body />
</soap:Envelope>
'''
request_doc = req.encode('utf-8')
pwd = 'password'
uname = 'username'
url = 'https://url.com
soap = objectify.fromstring(request_doc)
#here is my problem
soap.Header.HTNGHeader.From.Credential.userName = uname
soap.Header.HTNGHeader.From.Credential.password = pwd
soap_post = etree.tostring(soap)
url = 'https://connect.channelrush.net/reservationreceive/pickup?providerId=2'
res = post(url, data=soap_post)
res_obj = objectify.fromstring(res.text.encode('utf-8'))
pp.pprint(res.text)
使用 lxml.objectify 我得到以下异常:
File "f:\Dropbox\pms\channel_rush_interface_objectify.py", line 36, in <module>
soap.Header.HTNGHeader.From.Credential.userName = uname
File "c:\Python34\Lib\site-packages\lxml\objectify.pyd", line 230, in lxml.objectify.ObjectifiedElement.__getattr__ (src\lxml\objectify.c:4443)
File "c:\Python34\Lib\site-packages\lxml\objectify.pyd", line 451, in lxml.objectify._lookupChildOrRaise (src\lxml\objectify.c:7228)
builtins.AttributeError: no such child: {http://schemas.xmlsoap.org/soap/envelope/}HTNGHeader
任何人都可以指出如何让 lxml.objectify 工作吗?我应该坚持使用 xmltodict 吗?
来自lxml.objectify documentation:
During tag lookups, namespaces are handled mostly behind the scenes. If you access a child of an Element without specifying a namespace, the lookup will use the namespace of the parent. ... To access an element in a different namespace than its parent, you can use getattr() ... For convenience, there is also a quick way through item access. [examples removed]
对于你的情况,尝试:
soap.Header["{http://htng.org/1.1/Header/}HTNGHeader"].From.Credential.userName = uname
soap.Header["{http://htng.org/1.1/Header/}HTNGHeader"].From.Credential.password = pwd