Скрипт Python для синтаксического анализа XML-файла в Json

Как поживаешь? Мне нужно сделать сценарий для синтаксического анализа входного файла xml в файл json. Я старался изо всех сил, но было бы хорошо, если бы вы могли проверить это и помочь мне улучшить его. Идея в том, что я не использую objectify библиотек, которые напрямую конвертируют файлы. Я должен написать эти сценарии, по крайней мере, со следующими свойствами: —

  1. Тип сиденья / элемента (сиденье, кухня, ванная и т. Д.) —

  2. Элемент списка

  3. Идентификационный номер места (17A, 18A)

  4. Стоимость места

  5. Класс кабины

  6. Доступность

Кстати, мне не удалось найти тип сиденья / элемента для каждого сиденья.

import json
import xml.dom.minidom
from collections import OrderedDict


xmlFile = xml.dom.minidom.parse("seatmap1.xml")


def set_amount(element_to_analyze, element_to_change):
    if element_to_analyze.getAttribute('AvailableInd') == 'true':
        element_to_change['seat_price'] = seat.getElementsByTagName('ns:Service')[0].getElementsByTagName(
            'ns:Fee')[0].getAttribute('Amount')


def str_to_bool(s):
    if s == 'true':
        return True
    else:
        return False


flight_data = OrderedDict()

if xmlFile.getElementsByTagName('Document').length == 0:
    plane_data = xmlFile.getElementsByTagName('ns:FlightSegmentInfo')[0]
    flight_data['FlightNumber'] = plane_data.getAttribute('FlightNumber')
    flight_data['DepartureDateTime'] = plane_data.getAttribute('DepartureDateTime')
    flight_data['DepartureAirport'] = plane_data.getElementsByTagName('ns:DepartureAirport')[0].getAttribute(
        'LocationCode')
    flight_data['ArrivalAirport'] = plane_data.getElementsByTagName('ns:ArrivalAirport')[0].getAttribute('LocationCode')
    plane = xmlFile.getElementsByTagName('ns:CabinClass')
    cabin_object = OrderedDict()  # NS CABIN CLASS
    for cabin_class in plane:
        cabin = cabin_class.getElementsByTagName('ns:RowInfo')
        cabin_type = cabin[0].getAttribute('CabinType')
        for row_group in cabin:
            row_object = OrderedDict()  # NS ROW INFO
            seat_group = row_group.getElementsByTagName('ns:SeatInfo')
            for seat in seat_group:
                seat_details = OrderedDict()
                details = seat.getElementsByTagName('ns:Summary')[0]
                seat_details['seat'] = seat.getElementsByTagName('ns:')
                seat_details['seat_id'] = details.getAttribute('SeatNumber')
                seat_details['cabin_class'] = cabin_type
                seat_details['availability'] = str_to_bool(details.getAttribute('AvailableInd'))
                set_amount(details, seat_details)
                row_object[details.getAttribute('SeatNumber')[-1]] = seat_details
            cabin_object[row_group.getAttribute('RowNumber')] = row_object
    flight_data['Rows'] = cabin_object
    with open('_parsed.json', 'w') as outfile:
        outfile.write(json.dumps(flight_data))

Это мой xml файл

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <ns:OTA_AirSeatMapRS Version="1"
            xmlns:ns="http://www.opentravel.org/OTA/2003/05/common/">
            <ns:Success/>
            <ns:SeatMapResponses>
                <ns:SeatMapResponse>
                    <ns:FlightSegmentInfo DepartureDateTime="2020-11-22T15:30:00" FlightNumber="1179">
                        <ns:DepartureAirport LocationCode="LAS"/>
                        <ns:ArrivalAirport LocationCode="IAH"/>
                        <ns:Equipment AirEquipType="739"/>
                    </ns:FlightSegmentInfo>
                    <ns:SeatMapDetails>
                        <ns:CabinClass Layout="AB EF" UpperDeckInd="false">
                            <ns:RowInfo CabinType="First" OperableInd="true" RowNumber="1">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="1A"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="2" ExitRowInd="false" GalleyInd="false" GridNumber="2" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="1B"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="4" ExitRowInd="false" GalleyInd="false" GridNumber="4" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="1E"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="5" ExitRowInd="false" GalleyInd="false" GridNumber="5" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="1F"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                            </ns:RowInfo>
                            <ns:RowInfo CabinType="First" OperableInd="true" RowNumber="2">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="2A"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="2" ExitRowInd="false" GalleyInd="false" GridNumber="2" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="2B"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="4" ExitRowInd="false" GalleyInd="false" GridNumber="4" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="2E"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="5" ExitRowInd="false" GalleyInd="false" GridNumber="5" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="2F"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                            </ns:RowInfo>
                        </ns:CabinClass>
                        <ns:CabinClass Layout="ABC DEF" UpperDeckInd="false">
                            <ns:RowInfo CabinType="Economy" OperableInd="true" RowNumber="7">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="7A"/>
                                    <ns:Features extension="Lavatory">Other_</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="2" ExitRowInd="false" GalleyInd="false" GridNumber="2">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="7B"/>
                                    <ns:Features extension="Lavatory">Other_</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="3" ExitRowInd="false" GalleyInd="false" GridNumber="3">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="7C"/>
                                    <ns:Features extension="Lavatory">Other_</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="true" ColumnNumber="5" ExitRowInd="false" GalleyInd="false" GridNumber="5" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="7D"/>
                                    <ns:Features>BlockedSeat_Permanent</ns:Features>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="true" ColumnNumber="6" ExitRowInd="false" GalleyInd="false" GridNumber="6" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="7E"/>
                                    <ns:Features>BlockedSeat_Permanent</ns:Features>
                                    <ns:Features>Center</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="true" ColumnNumber="7" ExitRowInd="false" GalleyInd="false" GridNumber="7" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="7F"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                            </ns:RowInfo>
                            <ns:RowInfo CabinType="Economy" OperableInd="true" RowNumber="8">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="true" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="true" SeatNumber="8A"/>
                                    <ns:Status>Held</ns:Status>
                                    <ns:Features extension="Limited Recline">Other_</ns:Features>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="true" ColumnNumber="2" ExitRowInd="false" GalleyInd="false" GridNumber="2" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="true" SeatNumber="8B"/>
                                    <ns:Status>Held</ns:Status>
                                    <ns:Features extension="Limited Recline">Other_</ns:Features>
                                    <ns:Features>Center</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="true" ColumnNumber="3" ExitRowInd="false" GalleyInd="false" GridNumber="3" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="true" SeatNumber="8C"/>
                                    <ns:Status>Held</ns:Status>
                                    <ns:Features extension="Limited Recline">Other_</ns:Features>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="5" ExitRowInd="false" GalleyInd="false" GridNumber="5" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="true" SeatNumber="8D"/>
                                    <ns:Status>Held</ns:Status>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="6" ExitRowInd="false" GalleyInd="false" GridNumber="6" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="8E"/>
                                    <ns:Features>Center</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="7" ExitRowInd="false" GalleyInd="false" GridNumber="7" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="8F"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                            </ns:RowInfo>
                            <ns:RowInfo CabinType="Economy" OperableInd="true" RowNumber="9">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="true" SeatNumber="9A"/>
                                    <ns:Status>Held</ns:Status>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="2" ExitRowInd="false" GalleyInd="false" GridNumber="2" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="9B"/>
                                    <ns:Features>Center</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="3" ExitRowInd="false" GalleyInd="false" GridNumber="3" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="9C"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="5" ExitRowInd="false" GalleyInd="false" GridNumber="5" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="9D"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="6" ExitRowInd="false" GalleyInd="false" GridNumber="6" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="9E"/>
                                    <ns:Features>Center</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="7" ExitRowInd="false" GalleyInd="false" GridNumber="7" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="9F"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                            </ns:RowInfo>
                            <ns:RowInfo CabinType="Economy" OperableInd="true" RowNumber="10">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="10A"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="2" ExitRowInd="false" GalleyInd="false" GridNumber="2" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="10B"/>
                                    <ns:Features>Center</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="3" ExitRowInd="false" GalleyInd="false" GridNumber="3" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="10C"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="5" ExitRowInd="false" GalleyInd="false" GridNumber="5" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="10D"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="6" ExitRowInd="false" GalleyInd="false" GridNumber="6" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="10E"/>
                                    <ns:Features>Center</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="7" ExitRowInd="false" GalleyInd="false" GridNumber="7" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="10F"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                            </ns:RowInfo>
                            <ns:RowInfo CabinType="Economy" OperableInd="true" RowNumber="11">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="11A"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="2" ExitRowInd="false" GalleyInd="false" GridNumber="2" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="11B"/>
                                    <ns:Features>Center</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="3" ExitRowInd="false" GalleyInd="false" GridNumber="3" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="11C"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="5" ExitRowInd="false" GalleyInd="false" GridNumber="5" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="11D"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="6" ExitRowInd="false" GalleyInd="false" GridNumber="6" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="11E"/>
                                    <ns:Features>Center</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="7" ExitRowInd="false" GalleyInd="false" GridNumber="7" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="11F"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                            </ns:RowInfo>
                            <ns:RowInfo CabinType="Economy" OperableInd="true" RowNumber="12">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="true" SeatNumber="12A"/>
                                    <ns:Status>Held</ns:Status>
                                    <ns:Features extension="Preferred">Other_</ns:Features>
                                    <ns:Features>Window</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="2" ExitRowInd="false" GalleyInd="false" GridNumber="2" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="true" SeatNumber="12B"/>
                                    <ns:Status>Held</ns:Status>
                                    <ns:Features extension="Preferred">Other_</ns:Features>
                                    <ns:Features>Center</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="3" ExitRowInd="false" GalleyInd="false" GridNumber="3" PlaneSection="Left">
                                    <ns:Summary AvailableInd="true" InoperativeInd="false" OccupiedInd="false" SeatNumber="12C"/>
                                    <ns:Features extension="Preferred">Other_</ns:Features>
                                    <ns:Features>Aisle</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                    <ns:Service CodeContext="Preferred">
                                        <ns:Fee Amount="4200" CurrencyCode="USD" DecimalPlaces="2">
                                            <ns:Taxes Amount="0" CurrencyCode="USD"/>
                                        </ns:Fee>
                                    </ns:Service>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="5" ExitRowInd="false" GalleyInd="false" GridNumber="5" PlaneSection="Right">
                                    <ns:Summary AvailableInd="true" InoperativeInd="false" OccupiedInd="false" SeatNumber="12D"/>
                                    <ns:Features extension="Preferred">Other_</ns:Features>
                                    <ns:Features>Aisle</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                    <ns:Service CodeContext="Preferred">
                                        <ns:Fee Amount="4200" CurrencyCode="USD" DecimalPlaces="2">
                                            <ns:Taxes Amount="0" CurrencyCode="USD"/>
                                        </ns:Fee>
                                    </ns:Service>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="6" ExitRowInd="false" GalleyInd="false" GridNumber="6" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="true" SeatNumber="12E"/>
                                    <ns:Status>Held</ns:Status>
                                    <ns:Features extension="Preferred">Other_</ns:Features>
                                    <ns:Features>Center</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="7" ExitRowInd="false" GalleyInd="false" GridNumber="7" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="true" SeatNumber="12F"/>
                                    <ns:Status>Held</ns:Status>
                                    <ns:Features extension="Preferred">Other_</ns:Features>
                                    <ns:Features>Window</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                </ns:SeatInfo>
                            </ns:RowInfo>
                            <ns:RowInfo CabinType="Economy" OperableInd="true" RowNumber="38">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1" PlaneSection="Left">
                                    <ns:Summary AvailableInd="true" InoperativeInd="false" OccupiedInd="false" SeatNumber="38A"/>
                                    <ns:Features>Window</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                    <ns:Service CodeContext="Economy">
                                        <ns:Fee Amount="1300" CurrencyCode="USD" DecimalPlaces="2">
                                            <ns:Taxes Amount="0" CurrencyCode="USD"/>
                                        </ns:Fee>
                                    </ns:Service>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="2" ExitRowInd="false" GalleyInd="false" GridNumber="2" PlaneSection="Center">
                                    <ns:Summary AvailableInd="true" InoperativeInd="false" OccupiedInd="false" SeatNumber="38B"/>
                                    <ns:Features>Center</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                    <ns:Service CodeContext="Economy">
                                        <ns:Fee Amount="1200" CurrencyCode="USD" DecimalPlaces="2">
                                            <ns:Taxes Amount="0" CurrencyCode="USD"/>
                                        </ns:Fee>
                                    </ns:Service>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="3" ExitRowInd="false" GalleyInd="false" GridNumber="3" PlaneSection="Left">
                                    <ns:Summary AvailableInd="true" InoperativeInd="false" OccupiedInd="false" SeatNumber="38C"/>
                                    <ns:Features>Aisle</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                    <ns:Service CodeContext="Economy">
                                        <ns:Fee Amount="1800" CurrencyCode="USD" DecimalPlaces="2">
                                            <ns:Taxes Amount="0" CurrencyCode="USD"/>
                                        </ns:Fee>
                                    </ns:Service>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="5" ExitRowInd="false" GalleyInd="false" GridNumber="5" PlaneSection="Right">
                                    <ns:Summary AvailableInd="true" InoperativeInd="false" OccupiedInd="false" SeatNumber="38D"/>
                                    <ns:Features>Aisle</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                    <ns:Service CodeContext="Economy">
                                        <ns:Fee Amount="1800" CurrencyCode="USD" DecimalPlaces="2">
                                            <ns:Taxes Amount="0" CurrencyCode="USD"/>
                                        </ns:Fee>
                                    </ns:Service>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="6" ExitRowInd="false" GalleyInd="false" GridNumber="6" PlaneSection="Center">
                                    <ns:Summary AvailableInd="true" InoperativeInd="false" OccupiedInd="false" SeatNumber="38E"/>
                                    <ns:Features>Center</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                    <ns:Service CodeContext="Economy">
                                        <ns:Fee Amount="1200" CurrencyCode="USD" DecimalPlaces="2">
                                            <ns:Taxes Amount="0" CurrencyCode="USD"/>
                                        </ns:Fee>
                                    </ns:Service>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="7" ExitRowInd="false" GalleyInd="false" GridNumber="7" PlaneSection="Right">
                                    <ns:Summary AvailableInd="true" InoperativeInd="false" OccupiedInd="false" SeatNumber="38F"/>
                                    <ns:Features>Window</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                    <ns:Service CodeContext="Economy">
                                        <ns:Fee Amount="1300" CurrencyCode="USD" DecimalPlaces="2">
                                            <ns:Taxes Amount="0" CurrencyCode="USD"/>
                                        </ns:Fee>
                                    </ns:Service>
                                </ns:SeatInfo>
                            </ns:RowInfo>
                            <ns:RowInfo CabinType="Economy" OperableInd="true" RowNumber="39">
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="1" ExitRowInd="false" GalleyInd="false" GridNumber="1" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="true" SeatNumber="39A"/>
                                    <ns:Status>Held</ns:Status>
                                    <ns:Features>Window</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="2" ExitRowInd="false" GalleyInd="false" GridNumber="2" PlaneSection="Center">
                                    <ns:Summary AvailableInd="true" InoperativeInd="false" OccupiedInd="false" SeatNumber="39B"/>
                                    <ns:Features>Center</ns:Features>
                                    <ns:Features extension="Chargeable">Other_</ns:Features>
                                    <ns:Service CodeContext="Economy">
                                        <ns:Fee Amount="1200" CurrencyCode="USD" DecimalPlaces="2">
                                            <ns:Taxes Amount="0" CurrencyCode="USD"/>
                                        </ns:Fee>
                                    </ns:Service>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="3" ExitRowInd="false" GalleyInd="false" GridNumber="3" PlaneSection="Left">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="39C"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="5" ExitRowInd="false" GalleyInd="false" GridNumber="5" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="39D"/>
                                    <ns:Features>Aisle</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="6" ExitRowInd="false" GalleyInd="false" GridNumber="6" PlaneSection="Center">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="39E"/>
                                    <ns:Features>Center</ns:Features>
                                </ns:SeatInfo>
                                <ns:SeatInfo BlockedInd="false" BulkheadInd="false" ColumnNumber="7" ExitRowInd="false" GalleyInd="false" GridNumber="7" PlaneSection="Right">
                                    <ns:Summary AvailableInd="false" InoperativeInd="false" OccupiedInd="false" SeatNumber="39F"/>
                                    <ns:Features>Window</ns:Features>
                                </ns:SeatInfo>
                            </ns:RowInfo>
                        </ns:CabinClass>
                    </ns:SeatMapDetails>
                </ns:SeatMapResponse>
            </ns:SeatMapResponses>
            <ns:Warnings>
                <ns:Warning Type="11" Code="59">ENSURE PASSENGER MEETS GOVERNMENT DESIGNATED EXIT ROW CRITERIA</ns:Warning>
                <ns:Warning Type="11" Code="450">Valid Credit Card Payment Types: ,VI,UP,MPVI,MC,AX,DS,DC,TP,JC</ns:Warning>
            </ns:Warnings>
        </ns:OTA_AirSeatMapRS>
    </soapenv:Body>
</soapenv:Envelope>

1 ответ
1

Здесь много всего происходит, и проблема очень плохо определена. Я понимаю, что вас попросили сделать это (где исходное описание проблемы?) Для заявления о приеме на работу, так что, возможно, они оставили кучу открытыми для интерпретации, но в любом случае:

Обычно в Интернете ходят слухи, что etree — это интерфейс синтаксического анализа XML, который больше похож на Pythonic по сравнению с minidom. Видеть https://stackoverflow.com/a/8022507/313768 Например. Очень неясно, будут ли ограничения производительности подталкивать вас к lxml. Я считаю, что интерфейс etree более естественен, поэтому я показал его в своем примере кода, но minidom «тоже в порядке». Не идеально, если вы часто просите все совпадающие теги обращать внимание только на первый. Я показал довольно строгую схему навигации xpath, которая не заставляет синтаксический анализатор выполнять поиск по всему дереву и запрашивает только один элемент, когда это требуется.

Ваш set_amount это несколько странный блок кода для извлечения в функцию. Он не имеет возвращаемых значений и изменяет element_to_change на месте. В целом функции подходят лучше, если они возвращают значения и не изменяют свои члены. Подход Python к этому совершенно слабый, но если вы когда-нибудь переключитесь на функциональный язык, это станет большим фактором.

Вы определяете str_to_bool но затем не использовать его в set_amount. Это настолько простая операция, что ее, вероятно, не стоит фиксировать в функции, и ее можно выполнить в строке с == 'true' сказуемое и нет if-заявления.

Ваше использование OrderedDict не обязательно для любая современная версия Python.

Ваш Document проверка выполняется наизнанку и в обратном направлении — вместо того, чтобы проверять наличие полностью несвязанного элемента, вы должны проверять наличие отсутствие элемента, на который вы полагаетесь, чтобы сгенерировать текущий тип документа. Это может быть представлено, например, как исключение, созданное конструктором в том виде, в котором он есть у меня. Более изящные шаблоны могут использовать фабрику, которая проверяет документ на синтаксическом разборе и раскручивает правильный класс загрузки, но ваш вопрос не имеет достаточного контекста, чтобы оправдать это.

Вы объединили две операции в одну: загрузку из XML в четко определенное представление в памяти и сериализацию в JSON-совместимые словари. Я показал, как их можно разделить.

Не звони outfile.write(dumps; просто позвони dump который принимает файловый формат.

Пример кода

Это сгенерирует результат, эквивалентный вашему.

import json
from datetime import datetime
from decimal import Decimal
from functools import partial
from typing import Iterable, Tuple, Optional, Dict, Any
from xml.etree import ElementTree
from xml.etree.ElementTree import Element

NAMESPACES = {
    'soapenv': 'http://schemas.xmlsoap.org/soap/envelope/',
    'ns': 'http://www.opentravel.org/OTA/2003/05/common/',
}
ns_find = partial(Element.find, namespaces=NAMESPACES)
ns_findall = partial(Element.findall, namespaces=NAMESPACES)


class Seat:
    __slots__ = (
        'available', 'cabin_type', 'seat_id', 'row', 'col', 'seat_price',
    )

    def __init__(self, seat: Element, cabin_type: str, row: str):
        summary = ns_find(seat, './ns:Summary')
        self.available = summary.attrib['AvailableInd'] == 'true'
        self.cabin_type = cabin_type

        seat_id = summary.attrib['SeatNumber']
        row_from_id = seat_id[:len(row)]
        if row != row_from_id:
            raise ValueError(f'Row {row} conflicts with seat ID {seat_id}')
        self.seat_id = seat_id
        self.row = row
        self.col = seat_id[len(row):]

        if self.available:
            self.seat_price: Optional[Decimal] = Decimal(
                ns_find(seat, './ns:Service/ns:Fee').attrib['Amount']
            )
        else:
            self.seat_price = None

    def __str__(self):
        return self.seat_id

    def as_dict(self) -> Dict[str, Any]:
        d = {
            'seat_id': self.seat_id,
            'cabin_class': self.cabin_type,
            'availability': self.available,
        }
        if self.seat_price is not None:
            d['seat_price'] = str(self.seat_price)
        return d

    @classmethod
    def get_row(cls, row: Element, cabin_type: str, row_no: str) -> Iterable[Tuple[str, 'Seat']]:
        for seat_elm in ns_findall(row, './ns:SeatInfo'):
            seat = cls(seat_elm, cabin_type, row_no)
            yield seat.col, seat


class AirSeatMap:
    __slots__ = ('flight', 'seat_map')

    def __init__(self, filename: str):
        root = ElementTree.parse(filename).getroot()

        response = ns_find(
            root,
            './soapenv:Body/ns:OTA_AirSeatMapRS'
            '/ns:SeatMapResponses/ns:SeatMapResponse'
        )
        if response is None:
            raise ValueError('This is probably not an AirSeatMap')

        self.flight = ns_find(response, './ns:FlightSegmentInfo')
        self.seat_map = ns_find(response, './ns:SeatMapDetails')

    @property
    def flight_number(self) -> str:
        return self.flight.attrib['FlightNumber']

    @property
    def departure_time(self) -> datetime:
        return datetime.fromisoformat(self.flight.attrib['DepartureDateTime'])

    @property
    def departure_airport(self) -> str:
        return ns_find(self.flight, './ns:DepartureAirport').attrib['LocationCode']

    @property
    def arrival_airport(self) -> str:
        return ns_find(self.flight, './ns:ArrivalAirport').attrib['LocationCode']

    @property
    def seats(self) -> Iterable[Tuple[str,
        Iterable[Tuple[str, Seat]]
    ]]:
        for cabin_class in ns_findall(self.seat_map, './ns:CabinClass'):
            for row in ns_findall(cabin_class, './ns:RowInfo'):
                cabin_type = row.attrib['CabinType']
                row_no = row.attrib['RowNumber']
                yield row_no, Seat.get_row(row, cabin_type, row_no)

    def as_dict(self) -> Dict[str, Any]:
        return {
            'FlightNumber': self.flight_number,
            'DepartureDateTime': self.departure_time.isoformat(),
            'DepartureAirport': self.departure_airport,
            'ArrivalAirport': self.arrival_airport,
            'Rows': {
                row_no: {
                    col_no: seat.as_dict()
                    for col_no, seat in row
                }
                for row_no, row in self.seats
            },
        }


def main():
    map = AirSeatMap("seatmap1.xml")
    with open('_parsed.json', 'w') as outfile:
        json.dump(map.as_dict(), outfile)


if __name__ == '__main__':
    main()

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *