Xml 如何从shell执行XPath一行程序?

Xml 如何从shell执行XPath一行程序?,xml,shell,xpath,cross-platform,Xml,Shell,Xpath,Cross Platform,有没有针对Ubuntu和/或CentOS的软件包,它有一个命令行工具,可以执行XPath一行程序,比如foo//element@attributefilename.xml或foo//element@attribute

有没有针对Ubuntu和/或CentOS的软件包,它有一个命令行工具,可以执行XPath一行程序,比如
foo//element@attributefilename.xml
foo//element@attribute
并逐行返回结果

我正在寻找一种可以让我只
apt获得install foo
yum install foo
然后开箱即用的东西,无需包装或其他修改

以下是一些接近的例子:

诺科吉里。如果我写这个包装,我可以用上面描述的方式调用包装:

#!/usr/bin/ruby

require 'nokogiri'

Nokogiri::XML(STDIN).xpath(ARGV[0]).each do |row|
  puts row
end
XML::XPath。将使用此包装器:

#!/usr/bin/perl

use strict;
use warnings;
use XML::XPath;

my $root = XML::XPath->new(ioref => 'STDIN');
for my $node ($root->find($ARGV[0])->get_nodelist) {
  print($node->getData, "\n");
}
xpath
from XML::xpath返回太多噪音,
--节点--
attribute=“value”

xml\u grep
from xml::Twig无法处理不返回元素的表达式,因此无法在不进行进一步处理的情况下用于提取属性值

编辑:

echo cat//element/@attribute | xmllint--shell filename.xml
返回类似于
xpath
的噪声

xmllint--xpath//element/@attributefilename.xml
返回
attribute=“value”

xmllint--xpath'string(//element/@attribute)'filename.xml
返回我想要的内容,但只针对第一个匹配

对于另一个几乎可以满足这个问题的解决方案,这里有一个XSLT,可用于计算任意XPath表达式(需要在XSLT处理器中使用dyn:evaluate支持):



使用
xsltproc--stringparam模式//元素/@属性--stringparam值运行。任意-xpath.xslt filename.xml

您应该尝试以下工具:

  • xmlstarlet
    :可以编辑、选择、转换。。。默认情况下未安装,xpath1
  • xmllint
    :默认情况下,通常与
    libxml2 utils
    、xpath1一起安装(请检查my,以使
    --xpath
    打开非常旧的版本和以换行符分隔的输出(v<2.9.9)
  • xpath
    :通过perl的模块
    XML::xpath
    ,xpath1安装
  • xml\u grep
    :通过perl的模块安装
    xml::Twig
    ,xpath1(有限的xpath使用)
  • xidel
    :xpath3
  • saxon lint
    :我自己的项目,在@Michael Kay的saxon-HE Java库上包装,xpath3
xmllint
附带了
libxml2 utils
(可以用作带有
--shell
开关的交互式shell)

xmlstarlet
xmlstarlet

xpath
随perl模块一起提供

xml\u grep
附带perl模块

xidel
is
xidel

saxon lint
使用,(+复古兼容性)

例:


.

您可能也会感兴趣。它提供了一种交互式模式,您可以在其中对文档执行任何操作:

open 1.xml ;
ls //element/@id ;
for //p[@class="first"] echo text() ;
您也可以尝试my。它不在存储库的包中,但您可以从网页下载它(它没有依赖项)

对于此任务,它具有简单的语法:

xidel filename.xml -e '//element/@attribute' 

它是支持XPath 2的罕见工具之一。

Saxon不仅会为XPath 2.0做这项工作,而且会为XQuery 1.0和(在商业版本中)3.0做这项工作。它不是作为Linux包提供的,而是作为jar文件提供的。语法(可以轻松地用简单的脚本包装)是

2020年更新

Saxon 10.0包括Gizmo工具,可以从命令行交互或批量使用

java net.sf.saxon.Gizmo -s:source.xml
/>show //element/@attribute
/>quit

一个很可能已经安装在系统上的软件包是
python lxml

python -c "from lxml.etree import parse; from sys import stdin; print('\n'.join(parse(stdin).xpath('//element/@attribute')))"
除了和,还有一些类似于和的
grep
-实用程序(包括
xml\u grep
而不是
xml\u grep2
)。在处理大型或大量XML文件以实现快速OneLiner或
Makefile
目标时,这些文件非常有用。
XML::Twig
对于
perl
脚本编写方法来说,当您希望比
$SHELL
xmllint
xstlproc
关闭时,特别适合使用呃


应用程序名称中的编号方案表明,“2”版本是基本相同工具的较新/较新版本,可能需要其他模块(或
perl
本身)的较新版本。

在我搜索maven pom.xml文件时,我遇到了这个问题。但是我有以下限制:

  • 必须跨平台运行
  • 必须存在于所有主要linux发行版上,无需安装任何附加模块
  • 必须处理复杂的xml文件,如maven pom.xml文件
  • 简单语法
我尝试了上述许多方法,但都没有成功:

  • python lxml.etree不是标准python发行版的一部分
  • xml.etree是但不能很好地处理复杂的maven pom.xml文件,挖掘不够深入
  • 由于未知原因,python xml.etree不处理maven pom.xml文件
  • xmllint也不起作用,核心转储通常在Ubuntu12.04“xmllint:使用libxml版本20708”
我遇到的解决方案稳定、简短,可以在许多平台上工作,而且成熟,就是ruby中的rexml lib内置:

ruby -r rexml/document -e 'include REXML; 
     puts XPath.first(Document.new($stdin), "/project/version/text()")' < pom.xml
ruby-rrexml/document-e'包括rexml;
将XPath.first(Document.new($stdin),“/project/version/text()”)置于
以下文章激发了我的灵感:


与Mike和clacke的答案类似,这里是python one liner(使用python>=2.5)从pom.xml文件获取构建版本,该文件绕过了以下事实:
java net.sf.saxon.Gizmo -s:source.xml
/>show //element/@attribute
/>quit
python -c "from lxml.etree import parse; from sys import stdin; print('\n'.join(parse(stdin).xpath('//element/@attribute')))"
ruby -r rexml/document -e 'include REXML; 
     puts XPath.first(Document.new($stdin), "/project/version/text()")' < pom.xml
python -c "import xml.etree.ElementTree as ET; \
  print(ET.parse(open('pom.xml')).getroot().find('\
  {http://maven.apache.org/POM/4.0.0}version').text)"
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<mydoctype xmlns="http://xml-namespace-uri" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xml-namespace-uri http://xsd-uri" format="20171221A" date="2018-05-15">

  <elem1 time="0.586" length="10.586">
      <elem2 value="cue-in" type="outro" />
  </elem1>

</mydoctype>
0.586 10.586 cue-in outro
xml sel -N ns="http://xml-namespace-uri" -t -m '//ns:elem1/ns:elem2' \
 -v ../@time -o " " -v '../@time + ../@length' -o " " -v @value -o " " -v @type -n file.xml
xml sel -N ns="http://xml-namespace-uri" -t -m '//ns:elem1/ns:elem2/..' \
 -v 'concat(@time, " ", @time + @length, " ", ns:elem2/@value, " ", ns:elem2/@type)' -n file.xml
xgrep.py "//element/@attribute" filename.xml ...
function htmlxpath() { python -c 'for x in __import__("lxml.html").html.fromstring(__import__("sys").stdin.read()).xpath(__import__("sys").argv[1]): print(x)' $1 }
> curl -s https://slashdot.org | htmlxpath '//title/text()'
Slashdot: News for nerds, stuff that matters
sudo pip3 install xpe