Как разбить один XML-файл на несколько на основе тегов - PullRequest
2 голосов
/ 04 июля 2019

У меня есть XML-файл с тегами.Я хочу разделить файлы следующим образом.

<?xml version="1.0" encoding="UTF-8"?>
<EMPRMART CREATION_DATE="08/20/2018 18:06:44" REPOSITORY_VERSION="187.96">
<REPOSITORY NAME="REP_DEV" VERSION="187" CODEPAGE="UTF-8" DATABASETYPE="Sybase">
<FOLDER NAME="MC_DEV" 
    <CONFIG DESCRIPTION ="Default ORDER configuration object" ISDEFAULT ="YES" NAME ="default_ORDER_config" VERSIONNUMBER ="1">
        <ATTRIBUTE NAME ="Advanced" VALUE =""/>
        <ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
    </CONFIG>
    <ORDER DESCRIPTION ="" ISVALID ="YES" 
        <ATTRIBUTE NAME ="Normal" VALUE =""/>
        <ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
    </ORDER>
    <ORDER DESCRIPTION ="" ISVALID ="YES" 
        <ATTRIBUTE NAME ="Medium" VALUE =""/>
        <ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
    </ORDER>
    <ORDER DESCRIPTION ="" ISVALID ="YES" 
        <ATTRIBUTE NAME ="Advanced" VALUE =""/>
        <ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
    </ORDER>
    <LOCATION DESCRIPTION ="" ISENABLED ="YES" 
    </LOCATION>
</FOLDER>
</REPOSITORY>
</EMPRMART>

Ниже приведен пример кода.Но он генерирует каждую строку в новый файл

awk  '
    BEGIN { RS = "</ORDER>" } 
    $0 ~ /[^[:blank:]\n]/ { 
        printf "%s\n", $0 RS >> FILENAME "_" ++i ".xml" 
    }
' test.xml

Я хочу разбить этот файл на основе только тегов ORDER, как указано ниже

File1.xml
    <ORDER DESCRIPTION ="" ISVALID ="YES" 
        <ATTRIBUTE NAME ="Normal" VALUE =""/>
        <ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
    </ORDER>        
File2.xml
    <ORDER DESCRIPTION ="" ISVALID ="YES" 
        <ATTRIBUTE NAME ="Medium" VALUE =""/>
        <ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
    </ORDER>
File3.xml
<ORDER DESCRIPTION ="" ISVALID ="YES" 
        <ATTRIBUTE NAME ="Advanced" VALUE =""/>
        <ATTRIBUTE NAME ="Order type" VALUE ="NO"/>
    </ORDER>

Ответы [ 3 ]

4 голосов
/ 04 июля 2019

Если вы используете gnu awk, это должно дать запрошенный результат.

awk '/<ORDER>/ {f=1;++a} f {print > "file_"a".xml"} /<\/ORDER>/ {f=0}' file

Он будет печатать только строки от <ORDER> до </ORDER> как раздел в файлах с именем file_1.xml, file_2.xml и т. Д.

1 голос
/ 04 июля 2019

При наличии любого awk в любой оболочке в каждом блоке UNIX:

awk '/<ORDER/{f=1; out="file_"(++c)".xml"} f{print > out} /<\/ORDER>/{close(out); f=0}' file

очевидно, что он хрупок, поскольку он просто выполняет сопоставление с регулярным выражением для текста, а не анализирует XML, но он будет работать для отправленного вами образцаи любой подобный текст.

0 голосов
/ 04 июля 2019

Чтобы добиться того, что вы просите, я бы не использовал awk, а скорее хороший XML-парсер, такой как xmlstarlet или xmlint.Здесь есть один неизвестный, и это общее количество узлов с именем ORDER.Мы могли бы записать расширенный XPath для выбора, но мы оставим его простым:

xmlstarlet sel -t -v 'count(//ORDER)' file.xml

Теперь, когда у вас есть счетчик, вы можете перебрать все случаи и записать в файлы:

#!/usr/bin/env bash
xmlfile=file.xml

n=$(xmlstarlet sel -t -v 'count(//ORDER)' file.xml)
for i in $(seq 1 $n); do
   xmlstarlet sel -t -m "//ORDER[${i}]" -c . $xmlfile > "File${i}.xml"
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...