Извлечение узлов из нескольких файлов XML - PullRequest
2 голосов
/ 01 июля 2010

У меня есть три xml-файла схожей структуры, и я хотел бы использовать xpath-выражение для извлечения всех соответствующих узлов в этих файлах и записи их в третий.

Знаете ли вы хороший инструмент для этого?

Я думаю о чем-то вроде

$supermagicxpathtool -x "//whoopdee" file1.xml file2.xml file3.xml > resultfile.xml

Ответы [ 6 ]

2 голосов
/ 01 июля 2010

XPath может только выбирать узлы, он не может записывать в файл.

В XPath 1.0 не существует стандартного способа ссылки на узлы одного выражения, принадлежащие более чем одному документу XML.,Если языком программирования, на котором размещается XPath, является XSLT, то узлы документов трех документов XML могут быть в трех отдельных xsl:variable s: $doc1, $doc2 и $doc3.

$doc1//whoopdee | $doc2//whoopdee | $doc3//whoopdee

В качестве альтернативы можно напрямую использовать функцию XSLT document():

    document('file1.xml')//whoopdee 
  | document('file2.xml')//whoopdee 
  | document('file3.xml')//whoopdee

Для вывода результата любого выражения XPath, используя XSLT, можно просто написать:

<xsl:copy-of select="$doc1//whoopdee | $doc2//whoopdee | $doc3//whoopdee">

или

<xsl:copy-of select=
   "document('file1.xml')//whoopdee 
  | document('file2.xml')//whoopdee 
  | document('file3.xml')//whoopdee
">

В XPath 2.0 можно использовать стандартную функцию doc() и не будет зависеть от хоста XPath.

Command-line :

Можно использовать любой XSLT-процессор, который позволяет создавать экземпляры командной строки.Большинство процессоров XSLT допускают это.Они также позволяют передавать простые параметры в командной строке - обычно в формате name=value.Наконец, большинство процессоров XSLT разрешают указывать конечный файл для результата в качестве опции.Вот ссылка на документацию Saxon о его использовании в командной строке:

http://www.saxonica.com/documentation/using-xsl/commandline.html

2 голосов
/ 01 июля 2010

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

1 голос
/ 02 июля 2010

Использование xml-cat из пакета xml-coreutils добавляет к Unix внешний вид:

xml-cat file1.xml file2.xml file3.xml | \
   xmlstarlet sel -R -t -c /root/whoopdee - | \
   xmlstarlet fo > resultfile.xml 
0 голосов
/ 04 июля 2010

Вы, похоже, ищете инструмент xpath, который находится в пакете libxml-xpath-perl в Ubuntu и, скорее всего, в дистрибутивах Debian и на основе.

xpath [-s suffix] [-p prefix] [-q] -e query [-e query] ... [file] ...
0 голосов
/ 02 июля 2010

Итак, опираясь на мой предыдущий пост, xmlstarlet, похоже, выполняет свою работу следующим образом:

xmlstarlet sel -R -t -c / -c "document('file2.xml')" -c "document('file3.xml')" file1.xml | \
       xmlstarlet sel -R -t -c /xml-select/*/whoopdee - | xmlstarlet fo > resultfile.xml 

xmlstarlet val resultfile.xml
0 голосов
/ 02 июля 2010

xmlstarlet может скопировать узел в другой документ (так что это кажется первым шагом к решению):

# code example from:
# "How to copy a node to another document",
# http://sourceforge.net/projects/xmlstar/forums/forum/226076/topic/3558346

xml sel -R -t -c / -c "document('f2.xml')" f1.xml | \
       xml ed -m /xml-select/Module_0 /xml-select/cnpsXML/Destinations/Module_0/Filter_1 | \
       xml sel -t -c /xml-select/* - | xml fo 

# In pseudo code:
# 1. Combine both documents into one (using -R to keep the combo a valid XML file - genius!)
# 2. Move the element from f2.xml to its final destination

Чтобы извлечь все совпадающие узлы в обычный (без тегов) текст или xsl, мы можем сделатьследующее:

xmlstarlet sel -t -m "//whoopdee" -v '@*' -v '.' -n file1.xml > resultfile

xmlstarlet sel -C -t -m "//whoopdee" -v '@*' -v '.' -n file1.xml > resultfile.xsl
xml tr resultfile.xsl file1.xml
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...