Python API XML解析
我使用Python解析从Tableau服务器通过API返回的一些XML。 涉及命名空间,我想我可能缺乏对其工作方式的基本理解。 这是我的XML看起来像:
<tsResponse version-and-namespace-settings>
<parent type="Project" id="1f2f3e4e-5d6d-7c8c-9b0b-1a2a3f4f5e6e" />
<permissions>
<workbook id="1a1b1c1d-2e2f-2a2b-3c3d-3e3f4a4b4c4d" name="Finance">
<owner id="9f9e9d9c-8b8a-8f8e-7d7c-7b7a6f6d6e6d"/>
</workbook>
<granteeCapabilities>
<group id="1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d"/>
<capabilities>
<capability name="Read" mode="Allow"/>
<capability name="Filter" mode="Allow"/>
<capability name="ViewUnderlyingData" mode="Allow"/>
<capability name="ExportImage" mode="Allow"/>
<capability name="ExportData" mode="Allow"/>
<capability name="AddComment" mode="Allow"/>
<capability name="ViewComments" mode="Allow"/>
<capability name="ShareView" mode="Allow"/>
</capabilities>
</granteeCapabilities>
</permissions>
</tsResponse>
以下是我正在运行的代码,并将其缩减到问题发生的位置。 我的目标是首先在给定的工作簿ID下标识每个组ID,然后查找组下的每个功能。
xmlns = {'t': 'http://tableau.com/api'}
test_response1 = []
test_response2 = []
url = "tableau.my.org/api/2.4/sites/siteid/workbooks/workbookid/permissions?pageSize=1000".format()
server_response_WB2 = requests.get(url, headers={'x-tableau-auth': auth_token})
test_response1.append(server_response_WB2.text)
server_response_WB2 = ET.fromstring(_encode_for_display(server_response_WB2.text))
permissions = server_response_WB2.findall('.//t:permissions', namespaces=xmlns)
for permission in permissions:
capabilities = permission.findall('granteeCapabilities')
test_response2.append(capabilities)
print test_response1
print test_response2
test_response1包含如下列表:
[[<Element '{http://tableau.com/api}permissions' at 0x3c07d70>],
[<Element '{http://tableau.com/api}permissions' at 0x3bb8dd0>]]
然而,test_response2返回空列表的列表:
[[], [], []]
在上面的代码中,我正在寻找'granteeCapabilities'作为标签。 我也尝试使用命名空间来查找它,如下所示:
capabilities = permission.findall('.//t:permissions/granteeCapabilities', namespaces=xmlns)
这将返回相同的结果。 空列表的列表。 为什么我能够在权限下查找数据,但不能在较低级别上查找数据?
如果问题可能与XML命名空间有关,那么您确实不应该忽略XML表单的名称空间部分,因为它是诊断问题和编写工作解决方案的基础。
我怀疑命名空间http://tableau.com/api
被声明为XML中的默认命名空间(没有前缀的命名空间),在这种情况下,所有没有前缀的后代元素都会从祖先隐式继承相同的命名空间。 这可以解释为什么granteeCapabilities
不适用于您,并且您应该尝试在此处添加前缀t
:
capabilities = permission.findall('t:granteeCapabilities', namespaces=xmlns)
如果你不需要permissions
元素的任何信息,你可以直接获得granteeCapabilities
:
capabilities = root.findall('.//t:granteeCapabilities', namespaces=xmlns)
以下是一个简短但完整的示例,演示解决方案:
raw = '''<tsResponse xmlns="http://tableau.com/api" xmlns:xsi="w3.org/2001/XMLSchema-instance" xsi:schemaLocation="tableau/com/api tableau.com/api/ts-api-2.4.xsd">
<parent type="Project" id="1f2f3e4e-5d6d-7c8c-9b0b-1a2a3f4f5e6e" />
<permissions>
<granteeCapabilities>
<group id="1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d"/>
<capabilities>
....
</capabilities>
</granteeCapabilities>
</permissions>
</tsResponse>'''
from xml.etree import ElementTree as ET
root = ET.fromstring(raw)
xmlns = {'t': 'http://tableau.com/api'}
permissions = root.findall('.//t:permissions', namespaces=xmlns)
for permission in permissions:
capabilities = permission.findall('t:granteeCapabilities', namespaces=xmlns)
print capabilities
eval.in demo
输出:
[<Element '{http://tableau.com/api}granteeCapabilities' at 0x402f430c>]
链接地址: http://www.djcxy.com/p/58805.html