У меня была проблема с пониманием того, что должен делать этот код, потому что он использует абстрактные имена переменных, такие как item
, child
, subchild
, и это затрудняет рассуждение о коде. Я не такой умный, поэтому я переименовал переменные в row
, tag
и column
, чтобы мне было легче видеть, что делает код. (В моей книге даже строка и столбец немного абстрактны, но я полагаю, что непрозрачность ввода XML вряд ли является вашей ошибкой.)
Вы есть 2 строки, но вы хотите 5 словарей, потому что у вас есть 5 <column>
тегов, и вы хотите, чтобы данные каждого <column>
находились в отдельном словаре. Но вы хотите, чтобы теги other в <row>
повторялись вместе с данными <column>
.
Это означает, что вам нужно создать словарь для каждого <row>
, затем для каждого <column>
, добавьте данные этого столбца в словарь, затем выведите их перед переходом к следующему столбцу.
Этот код делает упрощающее предположение, что все ваши <columns>
имеют одинаковую структуру, с ровно одним <question>
и ровно одним <answer>
и ничем иным. Если это предположение не выполняется, то <column>
может быть сообщено с устаревшими данными, которые он унаследовал от предыдущего <column>
в той же строке. Он также не выдаст вообще никакого вывода для любого <row>
, у которого нет хотя бы одного <column>
.
Код должен дважды пропустить через теги oop, один раз для не <column>
s и один раз для <column>
s. В противном случае он не может быть уверен, что он видел все не-1038 * теги, прежде чем он начнет выводить <column>
s.
Есть другие (без сомнения, более элегантные) способы сделать это, но я сохранить структуру кода как можно ближе к исходному, за исключением того, что имена переменных стали менее непрозрачными.
for row in root.find('./data'): # find all projects node
data = {} # dictionary to store content of each projects
for tag in row:
if tag.tag != "column":
data[tag.tag] = tag.text # add row to dictionary
# Now the dictionary data is built for the row level
for tag in row:
if tag.tag == "column":
for column in tag:
data[column.tag] = column.text
# Now we have added the column level data for one column tag
data_list.append(data.copy())
Вывод будет таким, как показано ниже. Порядок ключевых слов не сохраняется, потому что для удобства я использовал pprint.pprint
.
[{'answer': 'a1',
'product': '1',
'question': 'Q1',
'replica': '1',
'respondent': 'm0wxo5f6w42h3fot34m7s6xij',
'seqnr': '1',
'session': '1',
'timestamp': '10-06-16 11:30'},
{'answer': 'a2',
'product': '1',
'question': 'Q2',
'replica': '1',
'respondent': 'm0wxo5f6w42h3fot34m7s6xij',
'seqnr': '1',
'session': '1',
'timestamp': '10-06-16 11:30'},
{'answer': 'a3',
'product': '1',
'question': 'Q3',
'replica': '1',
'respondent': 'w42h3fot34m7s6x',
'seqnr': '1',
'session': '1',
'timestamp': '10-06-16 11:30'},
{'answer': 'a4',
'product': '1',
'question': 'Q4',
'replica': '1',
'respondent': 'w42h3fot34m7s6x',
'seqnr': '1',
'session': '1',
'timestamp': '10-06-16 11:30'},
{'answer': 'a5',
'product': '1',
'question': 'Q5',
'replica': '1',
'respondent': 'w42h3fot34m7s6x',
'seqnr': '1',
'session': '1',
'timestamp': '10-06-16 11:30'}]