无法解析使用rest api返回的xml响应

时间:2019-02-23 10:36:57

标签: python xml xml-parsing elementtree

我正在尝试使用xml ElementTree类来解析我的restapi api响应。 我的xml是

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope
    xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header>
        <h:ServerVersionInfo MajorVersion="15" MinorVersion="20" MajorBuildNumber="1643" MinorBuildNumber="20" Version="V2018_01_08"
            xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
        </s:Header>
        <s:Body>
            <m:FindFolderResponse
                xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
                <m:ResponseMessages>
                    <m:FindFolderResponseMessage ResponseClass="Success">
                        <m:ResponseCode>NoError</m:ResponseCode>
                        <m:RootFolder IndexedPagingOffset="4" TotalItemsInView="4" IncludesLastItemInRange="true">
                            <t:Folders>
                                <t:Folder>
                                    <t:FolderId Id="AQMkADAzNTg5ZjFmLWI2OTItNDFiOC1iNzg5LTNmOTJmOGUxYmUxNwAuAAADTM6dNOFmmUKiuKvh0ZUivQEAKpTTWhjp40e4J27GznKZBQACaFVC9AAAAA==" ChangeKey="AQAAABYAAAAqlNNaGOnjR7gnbsbOcpkFAAJov6Ax"/>
                                    <t:ParentFolderId Id="AQMkADAzNTg5ZjFmLWI2OTItNDFiOC1iNzg5LTNmOTJmOGUxYmUxNwAuAAADTM6dNOFmmUKiuKvh0ZUivQEAKpTTWhjp40e4J27GznKZBQAAAgEMAAAA" ChangeKey="AQAAAA=="/>
                                    <t:DisplayName>1</t:DisplayName>
                                    <t:TotalCount>0</t:TotalCount>
                                    <t:ChildFolderCount>0</t:ChildFolderCount>
                                    <t:UnreadCount>0</t:UnreadCount>
                                </t:Folder>
                                <t:Folder>
                                    <t:FolderId Id="AQMkADAzNTg5ZjFmLWI2OTItNDFiOC1iNzg5LTNmOTJmOGUxYmUxNwAuAAADTM6dNOFmmUKiuKvh0ZUivQEAKpTTWhjp40e4J27GznKZBQACaFVC9QAAAA==" ChangeKey="AQAAABYAAAAqlNNaGOnjR7gnbsbOcpkFAAJov6Az"/>
                                    <t:ParentFolderId Id="AQMkADAzNTg5ZjFmLWI2OTItNDFiOC1iNzg5LTNmOTJmOGUxYmUxNwAuAAADTM6dNOFmmUKiuKvh0ZUivQEAKpTTWhjp40e4J27GznKZBQAAAgEMAAAA" ChangeKey="AQAAAA=="/>
                                    <t:DisplayName>2</t:DisplayName>
                                    <t:TotalCount>0</t:TotalCount>
                                    <t:ChildFolderCount>0</t:ChildFolderCount>
                                    <t:UnreadCount>0</t:UnreadCount>
                                </t:Folder>
                                <t:Folder>
                                    <t:FolderId Id="AQMkADAzNTg5ZjFmLWI2OTItNDFiOC1iNzg5LTNmOTJmOGUxYmUxNwAuAAADTM6dNOFmmUKiuKvh0ZUivQEAKpTTWhjp40e4J27GznKZBQACaFVC9gAAAA==" ChangeKey="AQAAABYAAAAqlNNaGOnjR7gnbsbOcpkFAAJov6A1"/>
                                    <t:ParentFolderId Id="AQMkADAzNTg5ZjFmLWI2OTItNDFiOC1iNzg5LTNmOTJmOGUxYmUxNwAuAAADTM6dNOFmmUKiuKvh0ZUivQEAKpTTWhjp40e4J27GznKZBQAAAgEMAAAA" ChangeKey="AQAAAA=="/>
                                    <t:DisplayName>3</t:DisplayName>
                                    <t:TotalCount>0</t:TotalCount>
                                    <t:ChildFolderCount>0</t:ChildFolderCount>
                                    <t:UnreadCount>0</t:UnreadCount>
                                </t:Folder>
                                <t:TasksFolder>
                                    <t:FolderId Id="AQMkADAzNTg5ZjFmLWI2OTItNDFiOC1iNzg5LTNmOTJmOGUxYmUxNwAuAAADTM6dNOFmmUKiuKvh0ZUivQEAKpTTWhjp40e4J27GznKZBQAB+Vi2/gAAAA==" ChangeKey="BAAAABYAAAAqlNNaGOnjR7gnbsbOcpkFAAJov6A3"/>
                                    <t:ParentFolderId Id="AQMkADAzNTg5ZjFmLWI2OTItNDFiOC1iNzg5LTNmOTJmOGUxYmUxNwAuAAADTM6dNOFmmUKiuKvh0ZUivQEAKpTTWhjp40e4J27GznKZBQAAAgEMAAAA" ChangeKey="AQAAAA=="/>
                                    <t:DisplayName>Test_tasks</t:DisplayName>
                                    <t:TotalCount>2</t:TotalCount>
                                    <t:ChildFolderCount>0</t:ChildFolderCount>
                                    <t:UnreadCount>0</t:UnreadCount>
                                </t:TasksFolder>
                            </t:Folders>
                        </m:RootFolder>
                    </m:FindFolderResponseMessage>
                </m:ResponseMessages>
            </m:FindFolderResponse>
        </s:Body>
    </s:Envelope>
  

在我的xml响应中,我有3个文件夹和1个TaskFolder。现在我要   返回所有唯一文件夹的字典(id,changeKey)   项目。

这是我正在使用的代码

def __parse_createItem_response(xml_response):
    response = {}

    response_obj = et.XML(xml_response)
    body = None
    for e in response_obj:
        if e.tag == '{http://schemas.xmlsoap.org/soap/envelope/}Body':
            body = e
            for e1 in body:
                if e1.tag == '{http://schemas.microsoft.com/exchange/services/2006/messages}FindFolderResponse':
                    FindFolderResponse = e1
                    for e2 in FindFolderResponse:
                        if e2.tag == '{http://schemas.microsoft.com/exchange/services/2006/messages}ResponseMessages':
                            ResponseMessages = e2
                            for e3 in ResponseMessages:
                                if e3.tag == '{http://schemas.microsoft.com/exchange/services/2006/messages}FindFolderResponseMessage':
                                    FindFolderResponseMessage = e3
                                    if e3.attrib:
                                        ResponseClass = e3.attrib['ResponseClass']
                                        response['ResponseClass'] = ResponseClass
                                        if 'Success' == ResponseClass:
                                            for e4 in FindFolderResponseMessage:
                                                if e4.tag == '{http://schemas.microsoft.com/exchange/services/2006/messages}RootFolder':
                                                    Rootfolder = e4
                                                    for e5 in Rootfolder:
                                                        if e5.tag == '{http://schemas.microsoft.com/exchange/services/2006/types}Folders':
                                                            Folders = e5
                                                            for p in Folders:
                                                                if p.tag == '{http://schemas.microsoft.com/exchange/services/2006/types}Folder':
                                                                    folder = p
                                                                    for fid in folder:
                                                                        if fid.tag == '{http://schemas.microsoft.com/exchange/services/2006/types}FolderId':
                                                                            response['FolderId'] = fid.attrib['Id']
                                                                            if fid.attrib['ChangeKey']:
                                                                                response['ChangeKey'] = fid.attrib[
                                                                                    'ChangeKey']
                                        elif 'Error' == ResponseClass:
                                            for e4 in FindFolderResponseMessage:
                                                if e4.tag == '{http://schemas.microsoft.com/exchange/services/2006/messages}MessageText':
                                                    MessageText = e4.text
                                                    response['MessageText'] = MessageText
                                                elif e4.tag == '{http://schemas.microsoft.com/exchange/services/2006/messages}ResponseCode':
                                                    ResponseCode = e4.text
                                                    response['ResponseCode'] = ResponseCode

    return response

我得到的输出是->

  

{'FolderId':   'AQMkADAzNTg5ZjFmLWI2OTItNDFiOC1iNzg5LTNmOTJmOGUxYmUxNwAuAAADTM6dNOFmmUKiuKvh0ZUivQEAKpTTWhjp40e4J27GznKZBQACaFVC9gAAAA ==',   'ChangeKey':'AQAAABYAAAAqlNNaGOnjR7gnbsbOcpkFAAJov6A1',   'ResponseClass':'Success'}

它仅返回具有DispalyName 3的文件夹。 我正在犯什么错误。 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

我认为您所追求的回应应该更像这样:

{
    'ResponseClass': 'Success',
    'Folders': [{
        'FolderId': ...
        'ChangeKey': ...
    }, {
        'FolderId': ...
        'ChangeKey': ...
    }]
}

我还建议简化您的代码以使其更具可读性,尤其是通过使用辅助函数来提取元素并删除所用的缩进量。

将代码修改为以下内容可以使您更接近所追求的目标:

import xml.etree.ElementTree as et


def __parse_createItem_response(xml_response):
    response = {}

    response_obj = et.XML(xml_response)

    body = get_first_element_with_tag(response_obj, '{http://schemas.xmlsoap.org/soap/envelope/}Body')
    FindFolderResponse = get_first_element_with_tag(body, '{http://schemas.microsoft.com/exchange/services/2006/messages}FindFolderResponse')
    ResponseMessages = get_first_element_with_tag(FindFolderResponse, '{http://schemas.microsoft.com/exchange/services/2006/messages}ResponseMessages')
    FindFolderResponseMessage = get_first_element_with_tag(ResponseMessages, '{http://schemas.microsoft.com/exchange/services/2006/messages}FindFolderResponseMessage')

    if FindFolderResponseMessage.attrib:
        ResponseClass = FindFolderResponseMessage.attrib['ResponseClass']
        response['ResponseClass'] = ResponseClass

    if response.get('ResponseClass') == 'Success':
        RootFolder = get_first_element_with_tag(FindFolderResponseMessage, '{http://schemas.microsoft.com/exchange/services/2006/messages}RootFolder')
        Folders = get_first_element_with_tag(RootFolder, '{http://schemas.microsoft.com/exchange/services/2006/types}Folders')

        folders = []
        for Folder in Folders:

            if Folder.tag != '{http://schemas.microsoft.com/exchange/services/2006/types}Folder':
                continue

            FolderId = get_first_element_with_tag(Folder, '{http://schemas.microsoft.com/exchange/services/2006/types}FolderId')
            folder = {
                'FolderId': FolderId.attrib['Id']
            }
            if FolderId.attrib['ChangeKey']:
                folder['ChangeKey'] = FolderId.attrib['ChangeKey']
            folders.append(folder)

        response['Folders'] = folders

    elif response.get('ResponseClass') == 'Error':
        MessageText = get_first_element_with_tag(FindFolderResponseMessage, '{http://schemas.microsoft.com/exchange/services/2006/messages}MessageText')
        if MessageText:
            response['MessageText'] = MessageText.text

        ResponseCode = get_first_element_with_tag(FindFolderResponseMessage, '{http://schemas.microsoft.com/exchange/services/2006/messages}ResponseCode')
        if ResponseCode:
            response['ResponseCode'] = ResponseCode.text

    return response


def get_first_element_with_tag(parent_element, tag):
    for element in parent_element:
        if element.tag == tag:
            return element