Разделение XML-файла на несколько по заданным тегам
Я хочу разбить файл XML на несколько файлов. Моя рабочая станция очень ограничена Eclipse Mars с Xalan 2.7.1.
Я также могу использовать Python, но никогда не использовал его раньше.
<?xml version="1.0" encoding="UTF-8"?>
<root>
<row>
<NAME>Doe</NAME>
<FIRSTNAME>Jon</FIRSTNAME>
<GENDER>M</GENDER>
</row>
<row>
<NAME>Mustermann</NAME>
<FIRSTNAME>Max</FIRSTNAME>
<GENDER>M</GENDER>
</row>
</root>
Как я могу преобразовать их так
<?xml version="1.0" encoding="UTF-8"?>
<root>
<row>
<NAME>Doe</NAME>
<FIRSTNAME>Jon</FIRSTNAME>
<GENDER>M</GENDER>
</row>
</root>
Мне нужны все "строки"-данные в одном файле с заголовком. Приведенные выше данные являются лишь примером. Большая часть данных строки содержит 16 атрибутов, но время от времени она меняется.
3 ответа
Используйте Python ElementTree.
Создайте файл, например, xmlsplitter.py. Добавьте приведенный ниже код (где file.xml - это ваш xml-файл и предполагается, что в каждой строке есть уникальный элемент NAME.).
import xml.etree.ElementTree as ET
context = ET.iterparse('file.xml', events=('end', ))
for event, elem in context:
if elem.tag == 'row':
title = elem.find('NAME').text
filename = format(title + ".xml")
with open(filename, 'wb') as f:
f.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
f.write(ET.tostring(elem))
Запустить его с
python xmlsplitter.py
Или, если имена не уникальны:
import xml.etree.ElementTree as ET
context = ET.iterparse('file.xml', events=('end', ))
index = 0
for event, elem in context:
if elem.tag == 'row':
index += 1
filename = format(str(index) + ".xml")
with open(filename, 'wb') as f:
f.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
f.write(ET.tostring(elem))
Это код, который работает идеально.
import xml.etree.ElementTree as ET
context = ET.iterparse('filname.xml', events=('end', ))
for event, elem in context:
if elem.tag == 'row':
title = elem.find('NAME').text
filename = format(title + ".xml")
with open(filename, 'wb') as f:
f.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
f.write("<root>\n")
f.write(ET.tostring(elem))
f.write("</root>")
Есть отличный инструмент http://xmlstar.sourceforge.net/docs.php который может многое сделать с xml (однако это не pythonic).
Учитывая, что у вас есть 1.xml
файл с данными, как указано выше. И вам нужно разделить его на отдельные файлы с именами NNN.xml с элементом / root / row.
Просто позвоните в оболочке:
$ for ((i=1; i<=`xmlstarlet sel -t -v 'count(/root/row)' 1.xml`; i++)); do \
echo '<?xml version="1.0" encoding="UTF-8"?><root>' > NAME.xml;
NAME=$(xmlstarlet sel -t -m '/root/row[position()='$i']' -v './NAME' 1.xml); \
xmlstarlet sel -t -m '/root/row[position()='$i']' -c . -n 1.xml >> $NAME.xml; \
echo '</root>' >> NAME.xml
done
Теперь у вас есть куча XML-файлов, таких как Joe.xml