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

上一篇: Python API XML parsing

下一篇: Extracting nested namespace from a xml using lxml