Как получить плоский XML, чтобы внешние сущности сливались на верхний уровень - PullRequest
6 голосов
/ 07 января 2010

Я знаю, что это пограничный случай, действительно ли он относится к stackoverflow или суперпользователю, но, как кажется, здесь довольно много вопросов по «редактированию кода», я публикую его на SO.

У меня есть куча XML-файлов, которые кто-то в своей бесконечной мудрости решил взорвать на несколько файлов с помощью тегов, что в результате делает их отладку / редактирование огромным P-i-t-A. Поэтому я ищу:

  1. Способ в VIM открывать их в одном буфере (желательно, чтобы изменения сохранялись в правильных внешних файлах сущностей), ИЛИ;
  2. Способ расширения файлов в VIM, чтобы внешние объекты читались и заменялись в буфере ИЛИ;
  3. простой способ сделать это с помощью bash / sed / python в командной строке (или в .vimrc)

Файлы верхнего уровня могут включать новые файлы и т. Д., Кто знает, на скольких уровнях это должно быть рекурсивным ...

Вот пример макета того, как выглядит файл верхнего уровня:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foobar PUBLIC "foobar:dtd" "foobar.dtd" [

        <!ENTITY foo SYSTEM "foo.xml">

        <!ENTITY bar SYSTEM "bar.xml">
]>
<foo>
        <params>
                &foo;
        </params>
        <bar>
                &bar;
        </bar>
</foo>

EDIT : Список приведен в порядке предпочтения - если нет вариантов 1. или 2., награда за лучшее # 3 ...

РЕДАКТИРОВАТЬ 2 : Похоже, ответ @Gaby работает, но, к сожалению, только частично, если я не делаю что-то не так - я напишу какой-то инструмент, используя его ответ, и опубликую его здесь для улучшений. Конечно, решение № 1 или № 2 приветствуется ...:)

РЕДАКТИРОВАТЬ 3 : Хорошо, лучший не-Emacs -ответ получит награду;)

Заключение : Благодаря @hcayless у меня теперь есть работающее решение # 2, я добавил:

autocmd BufReadPost,FileReadPost *.xml silent %!xmllint --noent - 2> /dev/null

на мой .vimrc и все безумно дорого.

Ответы [ 3 ]

5 голосов
/ 13 января 2010

Если у вас установлен libxml2, xmllint, вероятно, сделает это за вас. В зависимости от вашей настройки вам может потребоваться больше параметров, но для вашего примера,

xmllint --noent foobar.xml

напечатает ваш файл на стандартный вывод со всеми разрешенными объектами. Должно быть достаточно легко обернуть вокруг него некоторые скрипты bash, чтобы сделать то, что вам нужно.

1 голос
/ 10 января 2010

Для опции # 3 вы можете взглянуть на pixdom и посмотрите документацию на pxdom 1.5 A реализация Python DOM

Параметры конфигурации DOM

Результат операции разбора зависит от параметров, установленных на LSParser.domConfig mapping. От по умолчанию, в соответствии с DOM спецификации, все разделы CDATA будут быть заменены простыми текстовыми узлами и все связанные ссылки на сущности будут заменено содержимым сущности см. Это включает в себя внешние ссылки на сущности и внешние подмножество.

включает сериализатор для сохранения документа в файл.

0 голосов
/ 13 января 2010

Вы ищете что-то подобное?

#!/opt/local/bin/python
import sys
if len(sys.argv) < 2:
    print "some files needed."
    sys.exit()

final = """
<?xml version="1.0" encoding="ISO-8859-1"?>
<nodes>
"""
for a in sys.argv[1:]:
    ca = a.replace(".xml","")
    final += "<" + ca + ">\n"
    infile = open(a)
    final += infile.read()
    final += "</" + ca + ">\n"  

final += "</nodes>\n"

outfile = open("final.xml", "w")
outfile.write(final)
outfile.close()
...