Если я правильно понял ваш вопрос, вам нужно пройтись по дереву XML, так что вы, вероятно, захотите иметь рекурсивную функцию, которая делает это. Примерно так:
import pandas as pd
import xml.etree.ElementTree as ET
tree = ET.parse('file.xml')
root = tree.getroot()
def f(elem, result):
result[elem.tag] = elem.text
cs = elem.getchildren()
for c in cs:
result = f(c, result)
return result
d = f(root, {})
df = pd.DataFrame(d, index=['values']).T
df
Out:
values
Transmission \n
TransmissionBody \n
level1 \n
level2 \n
level3 \n
level4 \n
level5 \n
level6 \n
ColA ABC
ColB 123
Обновление: Вот когда нам нужно сделать это для нескольких файлов XML. Я добавил еще один файл, похожий на исходный файл с ColA, строки ColB заменены на
<ColA>DEF</ColA>
<ColB>456</ColD>
Вот код:
def f(elem, result):
result[elem.tag] = elem.text
cs = elem.getchildren()
for c in cs:
result = f(c, result)
return result
result = {}
for file in glob.glob('*.xml'):
tree = ET.parse(file)
root = tree.getroot()
result = f(root, result)
df = pd.DataFrame(result, index=['values']).T
df
И вывод:
0 1
Transmission \n \n
TransmissionBody \n \n
level1 \n \n
level2 \n \n
level3 \n \n
level4 \n \n
level5 \n \n
level6 \n \n
ColA ABC DEF
ColB 123 456
В итоге я наткнулся на апплет Java-загрузчика с открытым исходным кодом и нашел все, что мне нужно было знать, в его коде. Вот ссылки на сообщение в блоге, описывающее это, а также источник:
Apache common - очень хороший вариант. Apache common позволяет настраивать следующие вещи.
Только мои 2 цента:
Это основано на ответе Тулера (на момент написания есть ошибка). Я немного изменил его, поэтому вот моя версия ответа Tuler и mmyers (кажется, я не могу редактировать их ответ). Я хотел попытаться сделать это немного чище и быстрее. Помимо ошибки (которую я обсуждаю в комментариях к их ответу), большая проблема, с которой я столкнулся с их версией, заключается в том, что она создает новый CountingOutputStream
при каждой записи. Это может обойтись очень дорого с точки зрения памяти - тонны выделений и сборок мусора. Меньшая проблема заключается в том, что он использует делегат, когда он может просто расширить MultipartEntity
. Не знаю, почему они выбрали это, поэтому я сделал это более привычным способом. Если кто-нибудь знает плюсы и минусы двух подходов, это было бы здорово. Наконец, метод FilterOutputStream # write (byte [], int, int) просто вызывает FilterOutputStream # write (byte) в цикле. Документация FOS рекомендует подклассы, переопределяющие это поведение и повышающие его эффективность. Лучший способ сделать это здесь - позволить базовому OutputStream обрабатывать запрос на запись.
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
public class CountingMultiPartEntity extends MultipartEntity {
private UploadProgressListener listener_;
private CountingOutputStream outputStream_;
private OutputStream lastOutputStream_;
// the parameter is the same as the ProgressListener class in tuler's answer
public CountingMultiPartEntity(UploadProgressListener listener) {
super(HttpMultipartMode.BROWSER_COMPATIBLE);
listener_ = listener;
}
@Override
public void writeTo(OutputStream out) throws IOException {
// If we have yet to create the CountingOutputStream, or the
// OutputStream being passed in is different from the OutputStream used
// to create the current CountingOutputStream
if ((lastOutputStream_ == null) || (lastOutputStream_ != out)) {
lastOutputStream_ = out;
outputStream_ = new CountingOutputStream(out);
}
super.writeTo(outputStream_);
}
private class CountingOutputStream extends FilterOutputStream {
private long transferred = 0;
private OutputStream wrappedOutputStream_;
public CountingOutputStream(final OutputStream out) {
super(out);
wrappedOutputStream_ = out;
}
public void write(byte[] b, int off, int len) throws IOException {
wrappedOutputStream_.write(b,off,len);
++transferred;
listener_.transferred(transferred);
}
public void write(int b) throws IOException {
super.write(b);
}
}
}