cla*_*cke 182 xml shell xpath cross-platform
对于Ubuntu和/或CentOS,是否有一个包,它有一个命令行工具,可以执行XPath单线程,foo //element@attribute filename.xml或者foo //element@attribute < filename.xml逐行返回结果?
我正在寻找一些可以让我只是apt-get install foo或者yum install foo然后只是开箱即用,没有包装或其他必要的改编的东西.
以下是一些接近的事例:
引入nokogiri.如果我写这个包装器,我可以用上面描述的方式调用包装器:
#!/usr/bin/ruby
require 'nokogiri'
Nokogiri::XML(STDIN).xpath(ARGV[0]).each do |row|
puts row
end
Run Code Online (Sandbox Code Playgroud)
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");
}
Run Code Online (Sandbox Code Playgroud)
xpath来自XML :: XPath返回太多噪音,-- NODE --和attribute = "value".
xml_grep 来自XML :: Twig无法处理不返回元素的表达式,因此无法在不进一步处理的情况下提取属性值.
编辑:
echo cat //element/@attribute | xmllint --shell filename.xml返回类似的噪音xpath.
xmllint --xpath //element/@attribute filename.xml回报attribute = "value".
xmllint --xpath 'string(//element/@attribute)' filename.xml 返回我想要的,但仅限于第一场比赛.
对于几乎满足该问题的另一个解决方案,这里有一个可用于评估任意XPath表达式的XSLT(需要dyn:在XSLT处理器中评估支持):
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:dyn="http://exslt.org/dynamic" extension-element-prefixes="dyn">
<xsl:output omit-xml-declaration="yes" indent="no" method="text"/>
<xsl:template match="/">
<xsl:for-each select="dyn:evaluate($pattern)">
<xsl:value-of select="dyn:evaluate($value)"/>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
运行xsltproc --stringparam pattern //element/@attribute --stringparam value . arbitrary-xpath.xslt filename.xml.
Gil*_*not 252
你应该尝试这些工具:
xmlstarlet :可以编辑,选择,转换...默认情况下不安装,xpath1xmllint:经常默认使用libxml2xpath1 安装(检查我的包装器是否有换行符分隔输出xpath:通过perl的模块XML::XPathxpath1 安装xml_grep:通过perl的模块安装XML::Twig,xpath1(有限的xpath用法)xidel:xpath3saxon-lint :我自己的项目,包装在@Michael Kay的Saxon-HE Java库xpath3上xmllint附带libxml2-utils(可用作--shell交换机的交互式外壳)
xmlstarlet是xmlstarlet.
xpath 附带perl的模块 XML::Xpath
xml_grep 附带perl的模块 XML::Twig
xidel 是 xidel
saxon-lint使用SaxonHE 9.6,XPath 3.x(+复古兼容性)
例如:
xmllint --xpath '//element/@attribute' file.xml
xmlstarlet sel -t -v "//element/@attribute" file.xml
xpath -q -e '//element/@attribute' file.xml
xidel -se '//element/@attribute' file.xml
saxon-lint --xpath '//element/@attribute' file.xml
Run Code Online (Sandbox Code Playgroud)
.
Ben*_*ela 18
你也可以尝试我的Xidel.它不在存储库的包中,但您可以从网页下载它(它没有依赖项).
它具有此任务的简单语法:
xidel filename.xml -e '//element/@attribute'
Run Code Online (Sandbox Code Playgroud)
它是支持XPath 2的这些工具中罕见的一种.
cla*_*cke 15
一个很可能已安装在系统上的软件包已经存在python-lxml.如果是这样,可以在不安装任何额外包的情况下实现:
python -c "from lxml.etree import parse; from sys import stdin; print '\n'.join(parse(stdin).xpath('//element/@attribute'))"
Run Code Online (Sandbox Code Playgroud)
Mic*_*Kay 10
Saxon不仅可以用于XPath 2.0,还可以用于XQuery 1.0和(商业版)3.0.它不是一个Linux包,而是一个jar文件.语法(您可以轻松地将其包装在一个简单的脚本中)是
java net.sf.saxon.Query -s:source.xml -qs://element/attribute
Run Code Online (Sandbox Code Playgroud)
Mik*_*ike 10
在我查询maven pom.xml文件的搜索中,我遇到了这个问题.但是我有以下限制:
我已经尝试了上述许多方法而没有成功:
我遇到的唯一解决方案是稳定,简短并且可以在许多平台上工作,而且成熟的是在ruby中内置的rexml lib:
ruby -r rexml/document -e 'include REXML;
puts XPath.first(Document.new($stdin), "/project/version/text()")' < pom.xml
Run Code Online (Sandbox Code Playgroud)
是什么让我发现这个是以下文章:
您可能也对xsh感兴趣.它具有交互模式,您可以使用该文档执行任何操作:
open 1.xml ;
ls //element/@id ;
for //p[@class="first"] echo text() ;
Run Code Online (Sandbox Code Playgroud)
clacke 的回答很好,但我认为只有当您的源代码是格式良好的 XML 而不是普通的 HTML 时才有效。
因此,对普通 Web 内容(不一定是格式良好的 XML 的 HTML 文档)执行相同操作:
echo "<p>foo<div>bar</div><p>baz" | python -c "from sys import stdin; \
from lxml import html; \
print '\n'.join(html.tostring(node) for node in html.parse(stdin).xpath('//p'))"
Run Code Online (Sandbox Code Playgroud)
并改为使用 html5lib(以确保您获得与 Web 浏览器相同的解析行为——因为与浏览器解析器一样,html5lib 符合 HTML 规范中的解析要求)。
echo "<p>foo<div>bar</div><p>baz" | python -c "from sys import stdin; \
import html5lib; from lxml import html; \
doc = html5lib.parse(stdin, treebuilder='lxml', namespaceHTMLElements=False); \
print '\n'.join(html.tostring(node) for node in doc.xpath('//p'))
Run Code Online (Sandbox Code Playgroud)