Как разделить xml файл на части
Перейти к содержимому

Как разделить xml файл на части

  • автор:

Разбить XML файл на несколько частей.

Есть что-то готовое для резки XML (хотя с трудом представляю как. ) на части. Мне надо распилить файл где-то на 20 частей.

Suntechnic ★★★★★
26.11.13 02:12:45 MSK

По каким критериям резать? Надо ли на выходе получать well-formed/valid XML?

Скорее всего, кури XPath и XSLT.

anonymous
( 26.11.13 02:16:44 MSK )

есть многое на свете, друг горацио, что и не снилось нашим мудрецам

chg ★★★★★
( 26.11.13 02:28:45 MSK )

xmllint —help | grep xpath; xslt

visual ★★★
( 26.11.13 02:36:13 MSK )
Последнее исправление: visual 26.11.13 02:36:24 MSK (всего исправлений: 1)

Ответ на: комментарий от anonymous 26.11.13 02:16:44 MSK

Надо ли на выходе получать well-formed/valid XML?

Да. Допустим порезать между тегами 2 уровня вложенности.

Suntechnic ★★★★★
( 26.11.13 02:50:14 MSK ) автор топика
Ответ на: комментарий от Suntechnic 26.11.13 02:50:14 MSK

Подозреваю тебе прийдется сделать это «аналитически». Используя любую библиотеку считывать, зная формат определять в место разрыва (зная формат его можно определить), например если дерево двухуровневое, можно складывать ~50% тегов в один файл и 50% в другой, дублируя корень. Не думаю что есть универсальный инструмент для такого. Это же как резать без рентгена.

trashymichael ★★★
( 26.11.13 10:07:14 MSK )
Ответ на: комментарий от trashymichael 26.11.13 10:07:14 MSK

Ну в итоге я так и сделал. Просто думал возможно есть инструмент.

Как разделить большой xml-файл размеров 1 гб на множество по 20 мб?

Мне дали большой xml-файл, который мне требуется импортировать на сайт, но компонент отвечающий за импорт принимает только файлы меньше 20 МБ. Можно ли с помощью алгоритма на python из одного большого xml-файла достать все данные и равномерно распределить на множество небольших по 20 и меньше мегабайт? Под «равномерно распределить» я имею ввиду что бы файл заканчивался на и в один файл не попадал и его дочерние элементы из другого файла. Каждый блок весит от силы полмегабайта-мегабайт. Пример одного блока в файле:

   path/to/img1.jpg path/to/img2.jpg path/to/img3.jpg  <item>Название</item>  Около 50-100 строк html кода  Product weight: 1.2 kg Package weight: 1.3 kg   

Отслеживать
задан 7 авг 2019 в 16:32
471 6 6 серебряных знаков 12 12 бронзовых знаков
У вас есть агрантия, что любой блок в этом XML не больше 20мб?
7 авг 2019 в 16:47

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

from lxml import etree data = """  path/to/img1.jpg path/to/img2.jpg path/to/img3.jpg  <item>Название</item>  Около 50-100 строк html кода  Product weight: 1.2 kg Package weight: 1.3 kg   """ data = data*3 # Для пример будет 3 одинаковых дерева class Saver: name = '/путь/к/название_файла_<>.xml' # Скобки '<>' - место для счетчика. start_id = 0 nblocks = 2 # ' # Т.к. у нас получается битый xml (множество одинаковых тегов в корне) parsed = etree.fromstring(data).findall('root') saver = Saver() for i in parsed: saver(etree.tostring(i, encoding='unicode')) del saver # Это удаляет объект saver и сохраняет последний файл. 

Не забудь убрать: data = data*3 При проблемах с кодировкой на Windows, замените ‘w’ на ‘ab’ в open и удалите encoding=’unicode’ из tostring .

Отслеживать
ответ дан 7 авг 2019 в 19:57
Anton Abrosimov Anton Abrosimov
2,233 9 9 серебряных знаков 26 26 бронзовых знаков
Комментарии не предназначены для расширенной дискуссии; разговор перемещён в чат.
7 авг 2019 в 21:44

Имя файла подкорректировал? name = ‘/tmp/блок_<>.xml’ ? Скобки <> в нем есть? Воткни print(name) после f.write(self._cur_block_str) и посмотри, куда запись идет. nblocks = 2 — количество блоков на один файл не слишком большое?

Как разделить xml-файл по тэгам с помощью PHP?

Немного предыстории: есть сайт на WordPress, на нем стоит WP All Export, который делает все заказы в один файл.
У этого плагина есть свои хуки https://www.wpallimport.com/documentation/advanced.
Необходимо разделить файл экспорта:
Orders-Export-26.xml (который можно загрузить по ссылке)

    2021-12-29 12:50:31  322 2021-12-29 12:50:31 2021-12-29 12:50:31 9001496000001  250002 
Berd Ivan Dorotheergasse 3 Habr 1010 ru
67576575@yandex.ru +74845451564
9002804000119
Berd Ivan Dorotheergasse 3 Habr 1010 ru
34987349875793845 1 100-004 1 6,00
2021-12-30 10:14:41 323 2021-12-30 10:14:41 2021-12-30 10:14:41 9001496000001 250002
Berd Ivan Dorotheergasse 3 Moscv 1010 ru
xnjnjzbotq@yandex.ru +74845451564
9002804000119
Berd Ivan Dorotheergasse 3 Moscv 1010 ru
34987349875793845 1 100-007 2 6,00 2 100-005 3 1,99

на файлы:
2021-12-29_12:50:31.xml

   2021-12-29 12:50:31  322 2021-12-29 12:50:31 2021-12-29 12:50:31 9001496000001  250002 
Berd Ivan Dorotheergasse 3 Habr 1010 ru
67576575@yandex.ru +74845451564
9002804000119
Berd Ivan Dorotheergasse 3 Habr 1010 ru
34987349875793845 1 100-004 1 6,00

2021-12-30_10:14:41.xml

   2021-12-30 10:14:41  323 2021-12-30 10:14:41 2021-12-30 10:14:41 9001496000001  250002 
Berd Ivan Dorotheergasse 3 Moscv 1010 ru
xnjnjzbotq@yandex.ru +74845451564
9002804000119
Berd Ivan Dorotheergasse 3 Moscv 1010 ru
34987349875793845 1 100-007 2 6,00 2 100-005 3 1,99

Все выходные файлы поместить в папку с названием исходного файла (в примере это Orders-Export-26)
Все заключается чтобы при каждом экспорте создавалась новая папка а в ней иметь по 1.xml на 1 заказ

  • Вопрос задан более года назад
  • 121 просмотр

Как разделить xml файл спомощью bat/cmd?

Если это невозможно в BAT/CMD , подскажите простую рабочую програмку для этого.

  • Вопрос задан более года назад
  • 571 просмотр

5 комментариев

Простой 5 комментариев

Saboteur @saboteur_kiev

боюсь что в bat/cmd это будет слишком сложно. Гораздо проще такое делать в bash или любом другом универсальном скриптовом языке.

Natasha000

Natasha000 @Natasha000 Автор вопроса

Saboteur, Немного предыстории : есть сайт на WordPress на нем стоит WP All Export который делает все заказы в один файл. А программе нужен 1 файл = 1 заказ.
Нужно что то простое — так как это придется выполнять постоянно перед внесением в программу на компьютере.

Saboteur @saboteur_kiev

Не пользовался WP All Export, но гугл показывает, что это достаточно мощный инструмент. Разве его нельзя перенастроить, чтобы он экспортировал в разные файлы?

Natasha000

Natasha000 @Natasha000 Автор вопроса

Saboteur, тех. поддержка говорит что это не возможно при кастомном xml (который у меня) , там вообще нет такой настройки чтоб делить на файлы.

Saboteur @saboteur_kiev

ну я бы такое написал на bash/perl/python, но не знаю есть у вас где это запускать.
На современной винде встроенный есть powershell, в котором я не силен.
Но именно на cmd/bat это делать действительно неудобно

Решения вопроса 0
Ответы на вопрос 3
Не ИТ-специалист

Если файл будет иметь именно такой вид, то это просто (при этом будут потеряны пустые строки, если они есть):

@echo off setlocal enableextensions enabledelayedexpansion :0 if "%~1" == "" ( set /p in="Входной файл: " call :0 !in! exit /b ) if not exist "%~1" ( echo "%~f1" не найден. endlocal exit /b 1 ) set /a i = 0 for /f "usebackq skip=1 delims=" %%L in ("%~1") do ( if "%%L" == "" ( set /a i += 1 (echo ^)>!i!.xml ) (echo(%%L)>>!i!.xml ) endlocal

— XML-формат не учитывается, идёт разделение по строкам , которые должны начинаться с начала строки и не иметь пробелов в конце строки.

Ответ написан более года назад
Нравится 2 8 комментариев

Кстати, в последнем echo явно не хватает закрывающей скобки. Но оно и так работает. Странно
Добавил скобку перед перенаправлением вывода — работает, но не правильно.
Привел к такому виду: (echo.%%L)>>!i!.xml . Работает правильно и все скобки на месте.

Поэкспериментировал еще со служебными символами, содержащимися в переменных.
Оказалось, что вполне можно работать с ними, только надо везде использовать восклицательные знаки для обращения к переменным. Тогда они не раскрываются в командной строке, это происходит где-то потом. Соответственно ошибок не возникает даже вне тела цикла. Ну и конечно нужно включать setlocal enabledelayedexpansion .
Что характерно, переменные цикла раскрываются в коммандную строку, но это не генерирует ошибки. Об этом вы писали в нашей прошлой дискуссии по этому поводу. Видимо этот момент как-то особенно обрабатывается в cmd.

Жаль, что не знал обо всем этом лет 10 назад 🙂
Свою позицию по работе со служебными символами, содержащимися в переменных, в батниках окончательно меняю.
Мой ответ не правильный.

res2001, открывающая скобка после команды echo — это не открывающая скобка в том смысле, что она не требует парной, это разделитель между командой echo и её аргументом вместо повсеместно предлагаемой, но потенциально опасной, точки. Я об этом здесь уже упоминал.

wisgest, Спасибо за разъяснения. Не знал, что можно кроме точки использовать что-то другое и в своей практике ни когда не сталкивался с проблеммами использования echo. Это, конечно, не исключает проявления этих проблем в дальнейшем.

Natasha000

Natasha000 @Natasha000 Автор вопроса

wisgest, Спасибо, но к сожалению я забыла написать теги root (как писал об этом сергей кузьмин, ). По этому этот бат не работает. Возможно ли удалять в бат фале сразу root тэги, а потом обрабатывать ?

sergueik

Natasha000, так есть у вас в исходном XML который хотите порезать рут таг или нет ?

повторяю PS с легкостью режет по одному файлу на post
делается так:

$curdir = (resolve-path '.').Path $data = [xml] (get-content ($curdir + '\' + $filename )) -join '' # https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmltextwriter?view=netframework-4.0 $cnt=1; $good_data.root.post | foreach-object < $post = $_ if ($debug)< [System.xml.XmlTextWriter]$w = new-object System.xml.XmlTextWriter([Console]::out) $post.WriteTo($w) >$f = "$\a$.xml" [System.xml.XmlTextWriter]$w = new-object System.xml.XmlTextWriter($f, [System.Text.Encoding]::Ascii) write-host ('write post to ' -f $cnt, $f) $post.WriteTo($w) $w.flush() $w.close() $cnt++ >

PS справляется и с добвалением root если его не было

$curdir = (resolve-path '.').Path $bad_data = (get-content ($curdir + '\' + $filename )) -join '' # strip the header $bad_data = $bad_data -replace '' , '' # wrap bad data in root element [xml]$good_data = [xml] (' ' -f '', ([char]10), $bad_data)

Natasha000

Natasha000 @Natasha000 Автор вопроса

сергей кузьмин, рут таг есть. Батник не режет кода есть рут таг
вот файл (на самом деле он куда больше, я просто удалила часть вложенных тэгов чтобы не захломлять)

    2021-12-20 15:21:26  313 2021-12-20 15:21:26  1 100-001 1 3,99     2021-12-30 10:14:41  323 2021-12-30 10:14:41  1 100-007 2 6,00  2 100-005 3 1,99    
@echo off setlocal enableextensions enabledelayedexpansion :0 if "%~1" == "" ( set /p in="Input file: " call :0 !in! exit /b ) if not exist "%~1" ( echo "%~f1" not found. endlocal exit /b 1 ) set /a i = 0 for /f "usebackq skip=1 delims=" %%L in ("%~1") do ( if "%%L" == "" ( set /a i += 1 (echo ^)>!i!.xml ) (echo(%%L)>>!i!.xml ) endlocal

к сожалению не работает.. нужно удалить «post» таг , возможно ли это добавить в этот бат файл ?

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

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