如何从外壳执行XPath单行?(How to execute XPath one-liners fr

2019-07-21 19:57发布

是否有一个包在那里,为Ubuntu和/或CentOS的,其具有一个命令行工具,它可以执行XPath单行样foo //element@attribute filename.xmlfoo //element@attribute < filename.xml并通过线返回结果行?

我在寻找的东西,让我刚刚apt-get install fooyum 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="'&#10;'"/>
    </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开关)

xmlstarletxmlstarlet

xpath自带Perl的模块XML::Xpath

xml_grep自带Perl的模块XML::Twig

xidelxidel

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_grep2XML::Twig (其包括xml_grep而非xml_grep2 )。 在快速oneliners或大或无数的XML文件时,这些可以说是相当有用Makefile目标。 XML::Twig特别好的工作了perl脚本的方法,当你想比你更AA位处理$SHELLxmllint 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?