Не удалось разобрать ответ XML, возвращенный с помощью API остальных - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь проанализировать свой ответ restpi api, используя класс xml ElementTree.Мой 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': 'Успех'}

Он возвращает толькопапка, имеющая DispalyName 3. Какую ошибку я делаю.Любая помощь будет высоко оценена.

1 Ответ

0 голосов
/ 23 февраля 2019

Я думаю, что ответ, который вы ищете, должен быть структурирован примерно так:

{
    '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
...