LinuxForum.Fans
Тема

Правка xml, опять..

Автор: 1000Mhz 14 сообщений 3056 просмотров
20.11.2014 17:54 · отредактировано #401826

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

text
...
<info>
    <value1>
        <value1 prop1="то самое (неверное) значение">
    </value1>
</info>
...

Проблема наверно уже типовая, должны же быть типовые решения? Если можно, с примером :)
У меня пока только идея заменить на "nil", но так некрасиво, лучше удалить совсем.

20.11.2014 23:03 · отредактировано #401851

1) Скрипт смотрит родительский тег и обнаруживает есть ли внутри него другие строки с тем же или иным тегом
2) Да есть - удаляется стока с открывающим и закрывающим тегом
3) Нет - удаляется весь родительский тег

То есть если

text
<info>
    <value1>
        <value1 prop1="то самое (неверное) значение">
    </value1>
</info>

Удаляется всё начиная с открывающего <info> включая закрывающий </info>

Если:

text
<info>
    <value1>
        <value1 prop1="то самое (неверное) значение">
    </value1>
    <sometag>
        <"что-то там другое">
    </sometag>
</info>
</info>

Удаляется от <value1> и включая </value1>

В общем случае. А вообще нужно видеть DTD

21.11.2014 01:14 #401857

Спасибо, Кэп! :) Если на шелл, то логичнее склеить все в одну строку и регуляркой выдернуть весь блок, но вопрос сколько займет обработка такой строки, которая может получится приличной длинны. Придется видимо разбираться со специальными инструментами для работы с xml..

21.11.2014 01:41 · отредактировано #401858

1000Mhz, я знаю про XML и алгоритмы. Про конкретные реализации скриптов shell - не ко мне, но ни разу не вижу необходимости каких-то гипотетических особых инструментов тут, задачи более чем стандартные. И да, DTD этого XML где?

21.11.2014 02:03 #401860

Зато я не знаю. Дальше какие-то дебри начинаются, остановлюсь-ка на самом первом варианте))

21.11.2014 02:32 #401861

1000Mhz, дело Ваше (в конкретном скрипте bash), будут вопросы по XML - обращайтесь. И таки третий раз: где DTD???

21.11.2014 02:51 #401862
"1000Mhz" написал:
<value1 prop1="то самое (неверное) значение"/>

у тебя ошибка в документе: тег не закрыт

[console] $ cat 1.xml
<?xml version="1.0" encoding="UTF-8" ?>
<doc>
<info>
<value1>
<value1 prop1="bad_value"/>
</value1>
</info>
<info>
<value1>
<value1 prop1="bad_value"/>
</value1>
<value1>
<value1 prop1="good_value"/>
</value1>
</info>
</doc>

$ xmlstarlet ed -d '//info/value1[value1[@prop1="bad_value"]]' -d '//info[not(*)]' 1.xml
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<info>
<value1>
<value1 prop1="good_value"/>
</value1>
</info>
</doc>
[/console]

ЗЫ: редактирование xml'я, как текст — это особый вид пытки...

21.11.2014 03:55 #401867

"1000Mhz" написал:
т. е. удалить строку можно только вместе со всем блоком:
что значит "со всем блоком? Какой уровень вложенности? <info> или только <value>?

В любом случае, можно на sed сделать, просто закинуть блоки в область удержания, проанализировать, и (не)выводить наружу.

пример просили, да?

пример текста
[console]$ cat t.txt
<info>
<value1>
<value1 prop1="bad">
</value1>
</info>
<info>
<value1>
<value1 prop1="good">
</value1>
</info>
[/console]

пример кода
[console]$ sed -rn '/<value1>/!{p;b};:l;H;n;\~</value1>~!bl;x;/bad/{z;h;b};p;z;x;p' t.txt
<info>
</info>
<info>

<value1>
<value1 prop1="good">
</value1>
</info>
[/console]
21.11.2014 04:07 #401869

Fat-Zer, огромное спасибо! Я на XPath застрял..
drBatty, вложенность от info включительно. Но вариант с sed выглядит немного жутковато, на мой дилетантский взгляд :)

21.11.2014 04:43 #401874

"1000Mhz" написал:
Но вариант с sed выглядит немного жутковато
ну это уже ваши проблемы на самом деле. Я учебник уже написал, если вы не осилили, то уже ничем помочь не смогу.
21.11.2014 08:56 #401889
"Fat-Zer" написал:
тег не закрыт

Ну я думаю, в реальном документе такой лажи нет, ТС тут дал так, для примера... Нет?

"drBatty" написал:
Какой уровень вложенности?

Как я сказал выше, нужно смотреть остаётся ли тег пустым. Если да, то его нужно удалять. И да, мы оба давая примеры не исправили незакрытый одиночный тег, тут Fat-Zer прав.

1000Mhz, DTD где?

21.11.2014 15:07 #401932
"stranger" написал:
DTD где?

Нету :)

"drBatty" написал:
.. если вы не осилили ..

Пока ниасилил. Но зачем в данном случае изобретать велосипеды, если xmlstarlet давно уже есть?

22.11.2014 02:10 #401971

"stranger" написал:
Как я сказал выше, нужно смотреть остаётся ли тег пустым. Если да, то его нужно удалять.
можно и такую логику сделать, но мне лень.

"stranger" написал:
И да, мы оба давая примеры не исправили незакрытый одиночный тег, тут Fat-Zer прав.
это не мы должны исправлять вход.

"1000Mhz" написал:
Пока ниасилил. Но зачем в данном случае изобретать велосипеды, если xmlstarlet давно уже есть?
всё зависит от задачи.
22.11.2014 22:19 #402037
"drBatty" написал:
можно и такую логику сделать

Нужно. На том стоит логика XML.

"drBatty" написал:
это не мы должны

Тут согласен.

Войдите или зарегистрируйтесь, чтобы ответить.