从多个xml文件中提取节点

时间:2010-07-01 15:10:54

标签: xml bash xpath

我有三个类似结构的xml文件,我想使用xpath-expression来提取这些文件中的所有匹配节点,并将它们写入第三个节点。

你知道一个很好的工具来处理这个问题吗?

我在想像

这样的东西
$supermagicxpathtool -x "//whoopdee" file1.xml file2.xml file3.xml > resultfile.xml

6 个答案:

答案 0 :(得分:2)

xmlstarlet可以提取节点,但我不确定它是否可以像这样加入结果。

答案 1 :(得分:2)

XPath只能选择节点,不能写入文件。

在XPath 1.0中,没有标准方法可以在属于多个XML文档的单个表达式节点中引用。如果托管XPath的编程语言是XSLT,那么三个XML文档的文档节点可以分为三个xsl:variable$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的主机。

<强>命令行

可以使用任何允许命令行实例化的XSLT处理器。大多数XSLT处理器都允许这样做。它们还允许在命令行中传递简单参数 - 通常采用格式name=value。最后,大多数XSLT处理器允许将结果的目标文件指定为选项。以下是其命令行用法的Saxon文档的链接:

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

答案 2 :(得分:1)

使用xml-coreutils包的xml-cat添加到Unix外观&amp;感觉:

xml-cat file1.xml file2.xml file3.xml | \
   xmlstarlet sel -R -t -c /root/whoopdee - | \
   xmlstarlet fo > resultfile.xml 

答案 3 :(得分:0)

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

答案 4 :(得分:0)

因此,基于我以前的帖子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

答案 5 :(得分:0)

您似乎正在寻找位于Ubuntu中的xpath包中的工具libxml-xpath-perl,而且很可能是基于Debian和发行版的发行版。

xpath [-s suffix] [-p prefix] [-q] -e query [-e query] ... [file] ...