我试图通过'请求'从python 3.4获取某些网络服务的数据。库。我需要获得一个有效的xml-string来解析' lxml'图书馆。但由于某些原因,xml中的数据编码不正确:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<xmlData>
<?xml version="1.0" encoding="UTF-8"?><Response><Data& gt;<Company>... etc.
</xmlData>
</soap:Body>
</soap:Envelope>
使用以下代码:
ssession = requests.Session()
session.get(target_url)
exml = session.post(target_url, data=__xml, headers=headers)
print(exml.text)
如何在没有符号的情况下提取数据,例如&#39;&gt;&#39;在XML内部?如果没有手动将>
符号替换为等效符号,这是否可行?
答案 0 :(得分:2)
目前,您的SOAP响应是有效且格式良好的XML。字符实体的原因是因为您有一个嵌入的XML文档,因此实际的标记无法显示该内部XML,以便整个响应保持有效。
简单地解析嵌入的XML,将其编码为字节对象以接受特殊声明字符,并在其自己的XML树中解析。
from io import BytesIO
import lxml.etree as ET
# same SOAP response code...
# ORIGINAL TREE
soap_doc = ET.parse(BytesIO(exml.text.encode('utf-8')))
embedded_data = soap_doc.findall(".//xmlData")[0].text.strip().encode('utf-8')
# NEW TREE
tree = ET.parse(BytesIO(embedded_data))
# OUTPUT TO FILE
with open('output.xml', 'wb') as f:
f.write(ET.tostring(tree, xml_declaration=True,
pretty_print=True, encoding='utf-8'))
#<?xml version='1.0' encoding='utf-8'?>
#<Response>
# <Data>
# <Company> </Company>
# </Data>
#</Response>
在此字符串上测试的上述代码完成了有效的<xmlData>
,因为OP省略了嵌入式XML的其余部分:
'''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<xmlData>
<?xml version="1.0" encoding="UTF-8"?><Response><Data><Company> </Company></Data></Response>
</xmlData>
</soap:Body>
</soap:Envelope>
'''
答案 1 :(得分:1)
可能有另一种方法可以做到这一点,但粗粒度的方法是创建一个你想要转换的字符表,只需替换它们;
replacements = {
">" : ">",
"<" : "<"
}
def replace(xml):
repl_str = xml
for char in replacements:
repl_str = repl_str.replace(char, replacements[char])
return repl_str
补充说明;这里可以找到一张小桌子w3schools entities
答案 2 :(得分:0)
您可以使用标准库的sax包中的unescape
功能。
>>> from xml.sax.saxutils import unescape
>>> escaped = """<?xml version="1.0" encoding="UTF-8"?><Response><Data><Company>"""
>>> unescape(escaped)
'<?xml version="1.0" encoding="UTF-8"?><Response><Data><Company>'
unescape
默认处理&符号和尖括号;您可以传递字典来处理其他替换。来自docs:
xml.sax.saxutils.unescape(data,entities = {})
Unescape'&amp;','&lt;'和'&gt;'在一串数据中。
您可以通过将字典作为可选实体参数传递来取消其他数据字符串。键和值必须都是 串;每个密钥将替换为其相应的值。 '&amp; amp','&lt;'和'&gt;'即使实体是,也总是没有转义 提供。