是否有一个包在那里,为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
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
从XML :: XPath返回噪音太大, -- NODE --
和attribute = "value"
。
xml_grep
从XML ::嫩枝不能处理不返回元件表达式,因此不能使用而无需进一步处理,以提取属性值。
编辑:
echo cat //element/@attribute | xmllint --shell filename.xml
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(需要达因:评价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>
与运行xsltproc --stringparam pattern //element/@attribute --stringparam value . arbitrary-xpath.xslt filename.xml
xsltproc --stringparam pattern //element/@attribute --stringparam value . arbitrary-xpath.xslt filename.xml
。
Answer 1:
你应该试试这些工具:
-
xmlstarlet
:可以编辑,选择,变换...默认没有安装,xpath1 -
xmllint
:通常默认安装libxml2
,xpath1(检查我的包装有行分隔输出 -
xpath
:通过Perl的模块安装XML::XPath
,xpath1 -
xml_grep
:通过Perl的模块安装XML::Twig
,xpath1(有限的XPath使用) -
xidel
:xpath3 -
saxon-lint
:我自己的项目,包装上@迈克尔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
- xmlstarlet页
- 男人xmllint
- XPath的页面
- xml_grep
- xidel
- 撒克逊丝带
。
Answer 2:
你也可以试试我的Xidel 。 它不是在库中的包,但你可以从网页上(它没有依赖)下载。
它有这个任务简单的语法:
xidel filename.xml -e '//element/@attribute'
它是罕见的,它支持的XPath 2这些工具之一。
Answer 3:
一个数据包,这是非常有可能被安装在系统上已经是python-lxml
。 如果是这样,这是可能的,无需安装任何额外的软件包:
python -c "from lxml.etree import parse; from sys import stdin; print '\n'.join(parse(stdin).xpath('//element/@attribute'))"
Answer 4:
撒克逊人会做到这一点不仅对XPath 2.0中,同时也为XQuery 1.0和(在商业版本)3.0。 它不来的Linux软件包,但作为一个jar文件。 语法(你可以在一个简单的脚本容易包装)是
java net.sf.saxon.Query -s:source.xml -qs://element/attribute
Answer 5:
在我的搜索查询的Maven的pom.xml文件,我跑翻过了这个问题。 不过,我有以下限制:
- 必须跨平台运行。
- 必须在所有主要的Linux发行存在没有任何额外的模块安装
- 必须处理复杂的XML的文件,如看到maven pom.xml文件
- 简单的语法
我已经尝试了许多上面没有成功:
- 蟒lxml.etree不是标准蟒分发的一部分
- xml.etree是但不处理的Maven复杂文件的pom.xml很好,没有挖得足够深
- 蟒蛇xml.etree不处理对不明原因的Maven的pom.xml文件
- xmllint也不管用,经常核心转储在Ubuntu 12.04“xmllint:使用的libxml版本20708”
我所遇到的溶液是稳定的,短期和工作在许多平台上,这是成熟的是红宝石内建的REXML lib目录下:
ruby -r rexml/document -e 'include REXML;
p XPath.first(Document.new($stdin), "/project/version/text()")' < pom.xml
什么启发了我觉得这是一个在下面的文章:
- 红宝石/ XML,XSLT和XPath教程
- IBM:Ruby on Rails和XML
Answer 6:
您可能也有兴趣XSH 。 它具有交互模式,你可以做任何你与文档一样:
open 1.xml ;
ls //element/@id ;
for //p[@class="first"] echo text() ;
Answer 7:
clacke的答案是伟大的,但我认为,只有当你的源格式良好的XML,无法正常工作的HTML。
所以,做同样的正常的Web内容的HTML文档是不一定良好的XML:
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'))"
而改用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'))
Answer 8:
除了XML :: XSH和XML :: XSH2有一些grep
样公用事业吸作为App::xml_grep2
和XML::Twig
(其包括xml_grep
而非xml_grep2
)。 在快速oneliners或大或无数的XML文件时,这些可以说是相当有用Makefile
目标。 XML::Twig
特别好的工作了perl
脚本的方法,当你想比你更AA位处理$SHELL
和xmllint
xstlproc
报价。
在该应用程序名的编号方案指示“2”的版本较新/后基本上相同的工具,这可能需要其他模块的更新版本(或版本perl
本身)。
Answer 9:
类似小李的和clacke的答案,这里是一个蟒蛇衬(使用Python> = 2.5),以从该回避的事实获取的pom.xml文件通常不会有DTD一个pom.xml文件获取内部版本或默认的命名空间,所以不会出现结构良好的与libxml:
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)"
测试在Mac和Linux,并且不需要安装任何额外的软件包。
Answer 10:
它承担提的是引入nokogiri本身附带了一个命令行工具,它应该与安装gem install nokogiri
。
您可能会发现这个博客帖子有用 。
Answer 11:
我试过一对夫妇的命令行实用工具的XPath,当我意识到我花太多时间使用Google,并找出他们是如何工作的,所以我写在Python中最简单的可能的XPath解析器做了我所需要的。
下面的脚本显示如果XPath表达式的计算结果为一个字符串,或示出了整个XML子节点,如果结果是节点的字符串值:
#!/usr/bin/env python
import sys
from lxml import etree
tree = etree.parse(sys.argv[1])
xpath = sys.argv[2]
for e in tree.xpath(xpath):
if isinstance(e, str):
print(e)
else:
print((e.text and e.text.strip()) or etree.tostring(e))
它采用lxml
- C语言编写的一个快速的XML解析器未包含在标准Python库。 与安装pip install lxml
。 在Linux / OSX可能需要用前缀sudo
。
用法:
python xmlcat.py file.xml "//mynode"
LXML也可以接受URL作为输入:
python xmlcat.py http://example.com/file.xml "//mynode"
提取的URL属性的外壳下节点即<enclosure url="http:...""..>)
python xmlcat.py xmlcat.py file.xml "//enclosure/@url"
Xpath的谷歌浏览器
作为一个不相关的边注:如果碰巧要运行对网页的标记XPath表达式,那么你可以从Chrome devtools直做到这一点:在Chrome中右键单击页面>选择检查,然后在DevTools控制台粘贴XPath表达式为$x("//spam/eggs")
在该网页上的所有作者:
$x("//*[@class='user-details']/a/text()")
Answer 12:
由于这个项目显然是相当新的,检查出https://github.com/jeffbr13/xq ,似乎周围的包装lxml
,但是这是你真正需要的(和发布使用于其他的答案LXML以及临时解决方案)
Answer 13:
这里有一个xmlstarlet用例从嵌套元素elem1,elem2时数据提取到从这种类型的XML文本中的一个线(也示出了如何处理名称空间):
<?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
在该片段中,-m嵌套elem2时相匹配,-v输出属性值(与表达式和相对寻址), - O文字文本,-n添加一个新行:
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
如果从elem1需要更多的属性,可以像下面这样做(也显示了CONCAT()函数):
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
注意与命名空间(IMO不必要的)并发症(NS,宣布与N),这让我几乎放弃了对XPath和xmlstarlet,写一个快速的ad-hoc转换器。
文章来源: How to execute XPath one-liners from shell?