Как получить плоский XML, чтобы внешние объекты были объединены на верхний уровень

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

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

  1. Способ в VIM открыть их в одном буфере (желательно, чтобы изменения были сохранены в правильных файлах внешних сущностей), OR;
  2. Способ расширения файлов в VIM, чтобы внешние объекты считывались и заменялись в буфере OR;
  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 …

EDIT 2 : Похоже, что ответ @Gaby работает, но, к сожалению, только частично, если я не делаю что-то не так – я напишу какой-то инструмент, используя свой ответ, и опубликую его здесь для улучшения. Конечно, решение # 1 или # 2 было бы оценено … 🙂

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

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

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

к моему .vimrc и все это hunky dory.

3 Solutions collect form web for “Как получить плоский XML, чтобы внешние объекты были объединены на верхний уровень”

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

 xmllint --noent foobar.xml 

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

Для варианта №3 вы можете взглянуть на пиксель и посмотреть документацию на pxdom 1.5. Реализация POM для DOM

Параметры DOMConfiguration

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

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

Вы ищете что-то вроде этого?

 #!/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() 
  • Twisted XmlStream: Как подключиться к событиям?
  • Хруст xml с python
  • Почему это выражение xpath возвращает пустой список?
  • Есть ли в Python быстрый XML-парсер, который позволяет мне начинать тег как смещение байтов в потоке?
  • Как добавить пространство имен в атрибут в lxml
  • Объединение большого количества XML-файлов
  • Как я могу сказать, что файл SVG без использования магического номера?
  • получить первый абзац из статьи в Википедии
  • Python - лучший язык программирования в мире.