проблема с десериализацией xml на объекты - нежелательное разделение по специальным символам - PullRequest
0 голосов
/ 26 сентября 2011

Я пытаюсь десериализовать XML в объекты, и у меня возникла проблема с кодированием различных элементов в дереве XML.

Пример XML:

<?xml version="1.0" encoding="utf-8"?>
<results>
  <FlightTravel>
    <QuantityOfPassengers>6</QuantityOfPassengers>
    <Id>N5GWXM</Id>
    <InsuranceId>330992</InsuranceId>
    <TotalTime>3h 00m</TotalTime>
    <TransactionPrice>540.00</TransactionPrice>
    <AdditionalPrice>0</AdditionalPrice>
    <InsurancePrice>226.56</InsurancePrice>
    <TotalPrice>9561.31</TotalPrice>
    <CompanyName>XXXXX</CompanyName>
    <TaxID>111-11-11-111</TaxID>
    <InvoiceStreet>Jagiellońska</InvoiceStreet>
    <InvoiceHouseNo>8</InvoiceHouseNo>
    <InvoiceZipCode>Jagiellońska</InvoiceZipCode>
    <InvoiceCityName>Warszawa</InvoiceCityName>
    <PayerStreet>Jagiellońska</PayerStreet>
    <PayerHouseNo>8</PayerHouseNo>
    <PayerZipCode>11-111</PayerZipCode>
    <PayerCityName>Warszawa</PayerCityName>
    <PayerEmail>no-reply@xxxx.pl</PayerEmail>
    <PayerPhone>123123123</PayerPhone>
    <Segments>
      <Segment0>
        <DepartureAirport>WAW</DepartureAirport>
        <DepartureDate>śr. 06 lip</DepartureDate>
        <DepartureTime>07:50</DepartureTime>
        <ArrivalAirport>VIE</ArrivalAirport>
        <ArrivalDate>śr. 06 lip</ArrivalDate>
        <ArrivalTime>09:15</ArrivalTime>
      </Segment0>
      <Segment1>
        <DepartureAirport>VIE</DepartureAirport>
        <DepartureDate>śr. 06 lip</DepartureDate>
        <DepartureTime>10:00</DepartureTime>
        <ArrivalAirport>SZG</ArrivalAirport>
        <ArrivalDate>śr. 06 lip</ArrivalDate>
        <ArrivalTime>10:50</ArrivalTime>
      </Segment1>
    </Segments>
  </FlightTravel>
</results>

Функция десериализации XML в python:

# -*- coding: utf-8 -*-

from lxml import etree
import codecs

class TitleTarget(object):
    def __init__(self):
        self.text = []
    def start(self, tag, attrib):
        self.is_title = True #if tag == 'Title' else False
    def end(self, tag):
        pass
    def data(self, data):
        if self.is_title:
            self.text.append(data)
    def close(self):
        return self.text

parser = etree.XMLParser(target = TitleTarget())

infile = 'Flights.xml'
results = etree.parse(infile, parser)

out = open('wynik.txt', 'w')
out.write('\n'.join(results))
out.close()

Вывод:

['6', 'N5GWXM', '330992', '3h 00m',' 540.00 ',' 0 ',' 226.56 ',' 9561.31 ',' XXXXX ',' 111-11-11-111 ',' Jagiello ',' ń ',' ska ',' 8 ',' Jagiello',' ñ ',' ska ',' Warszawa ',' Jagiello ',' ń ',' ska ',' 8 ', '11 -111', 'Warszawa', 'no-reply@xxxx.pl','123123123', 'WAW', 'ś', 'r.06 lip ', '07: 50', 'VIE', 'ś', 'r.06 lip ', '09: 15', 'VIE', 'ś', 'r.06 lip ', '10: 00', 'SZG', 'ś', 'r.06 lip ', '10: 50']

В предмете ' Jagiellońska ' есть специальный символ ' ¥ '.Когда парсер добавляет данные в массив, тогда char 'ñ' - это король разделенных символов, и мой вопрос: почему это происходит?Остальные элементы добавляются в массив правильно.В позиции '06r 06.lip' точно такая же ситуация.

1 Ответ

1 голос
/ 26 сентября 2011

Проблема в том, что метод data вашего целевого класса может вызываться более одного раза для каждого элемента.Это может произойти, например, если фидер пересекает границу блока.Похоже, это также может произойти, когда он попадает не в ASCII-символ.Это древняя легенда.Я не могу найти, где это задокументировано.Однако если вы измените свой целевой класс на что-то вроде следующего, это будет работать.Я проверил это на ваших данных.

class TitleTarget(object):
    def __init__(self):
        self.text = []
    def start(self, tag, attrib):
        self.is_title = True #if tag == 'Title' else False
        if self.is_title:
            self.text.append(u'')
    def end(self, tag):
        pass
    def data(self, data):
        if self.is_title:
            self.text[-1] += data
    def close(self):
        return self.text

Чтобы лучше понять, на что похож ваш вывод, выполните print repr(results) после вызова parse.Теперь вы должны увидеть такие нерасщепленные тексты, как

u'Jagiello\u0144ska\n    '
u'\u015br. 06 lip\n        '
...