python - 使用 Python 将 Atom 或 OData XML 文件转换为 OData Json 文件
问题描述
我一直在尝试将 PowerShell 脚本转换为 Python 代码以从 Sharepoint 下载列表文件。到目前为止,大部分编码部分已完成并执行良好。但是,当我将文件从 Sharepoint 下载到具有 .json 扩展名的本地驱动器时,文件内容与预期不符。
Sharepoint 列表内容类型为 => content-type: application/atom+xml;type=feed;charset=utf-8
,采用 xml 格式。由于我无法将内容保存为 .json 格式,因此我已将文件下载为 .xml 并使用 xmltodict python 包将其转换为 .json,到目前为止效果还不错。
这是我的实际查询:我们如何下载带有 .json 的 xml 内容或将 xml 文件转换为没有属性类型、标签和命名空间等的 json 文件?我们需要以下面的 PowerShell 脚本生成的输出格式下载文件,不带任何标签,只带有键值对。
我只是共享示例文件内容,而不是复制整个内容,因为它涉及一些敏感数据。
这是原子 xml 格式/Odata xml 的 Sharepoint Web url 内容。
<?xml version="1.0" encoding="utf-8"?><feed xml:base="https://myorg.sharepoint.com/sites/pwaeng/_api/" xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
<d:Created m:type="Edm.DateTime">2018-05-09T21:21:03Z</d:Created><d:AuthorId m:type="Edm.Int32">1344</d:AuthorId><d:EditorId m:type="Edm.Int32">1344</d:EditorId><d:OData__UIVersionString>1.0</d:OData__UIVersionString><d:Attachments m:type="Edm.Boolean">false</d:Attachments><d:GUID m:type="Edm.Guid">9ef38bd1-a098-4610-98a4-dbf7488a5a27</d:GUID></m:properties></content></entry></feed>
这是 Python 转换的 json 数据
{"feed": {"@xml:base": "https://myorg.sharepoint.com/sites/pwaeng/_api/", "@xmlns": "http://www.w3.org/2005/Atom", "@xmlns:d": "http://schemas.microsoft.com/ado/2007/08/dataservices",
"d:Created": {"@m:type": "Edm.DateTime", "#text": "2018-05-09T21:21:03Z"}, "d:AuthorId": {"@m:type": "Edm.Int32", "#text": "1344"}, "d:EditorId": {"@m:type": "Edm.Int32", "#text": "1344"}, "d:OData__UIVersionString": "1.0", "d:Attachments": {"@m:type": "Edm.Boolean", "#text": "false"}, "d:GUID": {"@m:type": "Edm.Guid", "#text": "9ef38bd1-a098-4610-98a4-dbf7488a5a27"}}}}}}
PowerShell 下载的 Json 文件
{"odata.metadata":"https://myorg.sharepoint.com/sites/pwaeng/_api/$metadata#SP.ListData.Program_x0020_RisksListItems","value":[{"odata.type":"SP.Data .Program_x0020_RisksListItem","odata.id":"a878d166-c19d-4c16-82b4-e150e7e49626","odata.etag":""2"","odata.editLink":"Web/Lists
"Created":"2018-05-09T21:21:03Z","AuthorId":1344,"EditorId":1344,"OData__UIVersionString":"1.0","Attachments":false,"GUID":"9ef38bd1-a098-4610-98a4-dbf7488a5a27"}]}
下面是 Python 代码的一部分。我已经尝试了大多数选项,但没有获得所需的输出。
listURL = webAbsoluteURL +
"/_api/web/lists/GetByTitle('" + List + "')/items"
#print(listURL)
count = 0
#print(type(str(count)))
fileName = "file_" + ListFolder.strip() + "_" + str(count) + "_" + date
#print(fileName)
xml_output = Filepath + "/" + fileName + ".xml" ##USe backslash in Windows
json_output = Filepath + "/" + fileName + ".json"
#print(output)
#print(userName, Password)
url = listURL
#ctx = ClientContext(url).with_credentials(UserCredential(userName, Password))
#web = ctx.web.get().execute_query()
#print("Web title: {0}".format(web.properties['Title']))
ctx_auth = AuthenticationContext(webAbsoluteURL)
token = ctx_auth.acquire_token_for_user(userName, Password)
#ctx = ClientContext(webAbsoluteURL, ctx_auth)
#print(token)
options = RequestOptions(webAbsoluteURL)
ctx_auth.authenticate_request(options)
#options.headers = {
#'accept' : 'text/html,application/xhtml+xml,application/xml',
#'content-type': 'application/atom+xml;type=feed;charset=utf-8',
#'X-RequestForceAuthentication' : 'true'
#}
response = requests.get(url, headers=options.headers, allow_redirects=True, timeout=60000)
#print(req.status_code)
#headers = {
#'accept' : 'application/json;odata=verbose',
#'content-type' : 'application/json;odata=verbose',
#'X-RequestForceAuthentication' : 'true'
#}
#response = requests.get(url, allow_redirects=True, headers=headers, timeout=60000)
#print(response.status_code)
with open(xml_output, 'wb') as file_save:
file_save.write(response.content)
with open(xml_output, 'r', encoding = "UTF-8") as xml_file:
data_dict = xmltodict.parse(xml_file.read()) # , attr_prefix='')
xml_file.close()
#json_data = json.dumps(data_dict, separators=(',', ':'))
#json_data = json.dumps(data_dict, indent=2)
json_data = json.dumps(data_dict)
#with open(json_output, 'w') as json_file:
# json.dump(data_dict, json_file)
# json_file.close()
with open(json_output, 'wb') as json_file:
json_file.write(json_data.encode("UTF-8"))
json_file.close()
解决方案
找到了解决方案,而不是使用 xml 到 json 解析器(xmltodict.parse)等,简单的解决方案是将这个“ ?&$format=json ”添加到 Web URL 的末尾。
XML_DATA_URL = https://myorg.sharepoint.com/sites/pwaeng/_api/projectdata/Tasks
JSON_FORMAT_URL = https://myorg.sharepoint.com/sites/pwaeng/_api/projectdata/Tasks?&$format=json
但是,这不适用于以下类型的 URL。
https://myorg.sharepoint.com/sites/pwaeng/_api/web/lists/GetByTitle('Program Risks')/items
https://myorg.sharepoint.com/sites/pwaeng/_api/web/lists/GetByTitle('Program Risks')/items?&$format=json
如果有人有任何建议,请在此处添加您的评论..
推荐阅读
- python - 如何合并两个具有重复列的数据框以连接每个字符串值?
- node.js - 当使用带有代理的 Puppeteer 请求 HTTPS 站点时,如何/何时/在何处设置标头?
- javascript - 算法的运行时间 Hackkerrank 插入排序问题
- css - 复选框单击输入。其他帖子的复选框被选中
- ruby-on-rails - 如何在 Rails 中创建具有多向关联的三重嵌套对象
- python - 使用python列出索引超出范围错误 - 线性搜索代码
- .net-core - .NET Core DbContext 阻止后续请求
- python - Two functional functions when called together creates an error
- automationanywhere - 我需要在名称中包含“RPA”的文件夹中打开一些文件。那么我怎样才能在任何地方的自动化中做到这一点呢?
- c++ - PyTorch C++ 扩展:访问半张量的数据