Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于XML命令行处理的Grep和Sed等价物_Xml_Command Line_Scripting - Fatal编程技术网

用于XML命令行处理的Grep和Sed等价物

用于XML命令行处理的Grep和Sed等价物,xml,command-line,scripting,Xml,Command Line,Scripting,在执行shell脚本时,数据通常位于单行记录(如csv)文件中。使用grep和sed处理这些数据非常简单。但是我必须经常处理XML,所以我非常希望有一种通过命令行编写访问XML数据的脚本的方法。最好的工具是什么?一些有前途的工具: :使用XPath和CSS选择器在ruby中解析HTML/XML DOM :弃用 : 使用其自身类似XPath的语法查询文档。用SML写的,所以 安装可能很困难 : 从SGML工具派生的XML工具包,包括sggrep,sgsort, xmlnorm和其他。使用自己的查

在执行shell脚本时,数据通常位于单行记录(如csv)文件中。使用
grep
sed
处理这些数据非常简单。但是我必须经常处理XML,所以我非常希望有一种通过命令行编写访问XML数据的脚本的方法。最好的工具是什么?

一些有前途的工具:

  • :使用XPath和CSS选择器在ruby中解析HTML/XML DOM

  • :弃用

  • : 使用其自身类似XPath的语法查询文档。用SML写的,所以 安装可能很困难

  • : 从SGML工具派生的XML工具包,包括
    sggrep
    sgsort
    xmlnorm
    和其他。使用自己的查询语法。文件是 非常正式。用C.LTXML2编写,声称支持XPath,XInclude 和其他W3C标准

  • : 使用XPath进行简单而强大的搜索。使用Perl编写 XML::LibXML和libxml2

  • : 支持XQuery,即XPath的扩展。为.NET框架编写

  • : Laird Breyer的工具包相当于GNU coreutils。讨论 关于理想的工具包应该包括哪些内容很有趣

  • : 用于比较两个xml文件的简单工具

  • :似乎没有debian、ubuntu、fedora或macports中的软件包,自2007年以来就没有发布过,并且使用非便携式构建自动化

xml coreutils似乎是文档记录最好、最面向UNIX的。JEdit有一个名为“XQuery”的插件,它为xml文档提供查询功能


不完全是命令行,但它可以工作

我发现xmlstarlet在这方面非常擅长

在大多数发行版存储库中也应该可用。以下是介绍性教程:


完全取决于你想做什么


XSLT可能是一条路,但有一条学习曲线。请注意,您可以提交参数。

XQuery可能是一个很好的解决方案。它(相对)容易学习,是W3C标准


我建议使用命令行处理器。

在Joseph Holsten的优秀列表中,我添加了Perl库XML::xpath附带的xpath命令行脚本。从XML文件中提取信息的好方法:

 xpath -q -e '/entry[@xml:lang="fr"]' *xml

还有
xml2
2xml
对。它将允许常用的字符串编辑工具处理XML

例如。q、 xml:

<?xml version="1.0"?>
<foo>
    text
    more text
    <textnode>ddd</textnode><textnode a="bv">dsss</textnode>
    <![CDATA[ asfdasdsa <foo> sdfsdfdsf <bar> ]]>
</foo>

文本
更多文本
DDSS
sdfsdfdsf]]>
xml2

/foo=
/foo=   text
/foo=   more text
/foo=   
/foo/textnode=ddd
/foo/textnode
/foo/textnode/@a=bv
/foo/textnode=dsss
/foo=
/foo=    asfdasdsa <foo> sdfsdfdsf <bar> 
/foo=
<bar><baz><textnode>ddd</textnode><textnode a="bv">dsss</textnode></baz></bar>
/foo=
/foo=文本
/foo=更多文本
/foo=
/foo/textnode=ddd
/foo/textnode
/foo/textnode/@a=bv
/foo/textnode=dsss
/福=
/foo=asfdasdsa sdfsdfdsf
/福=
xml2

/foo=
/foo=   text
/foo=   more text
/foo=   
/foo/textnode=ddd
/foo/textnode
/foo/textnode/@a=bv
/foo/textnode=dsss
/foo=
/foo=    asfdasdsa <foo> sdfsdfdsf <bar> 
/foo=
<bar><baz><textnode>ddd</textnode><textnode a="bv">dsss</textnode></baz></bar>
ddss

另外,还有
html2
/
2html

还有NetBSD xmltools的xmlsed和xmlgrep

您可以使用xmllint:

xmllint --xpath //title books.xml
应该与大多数发行版捆绑,也与Cygwin捆绑

$ xmllint --version
xmllint: using libxml version 20900
见:


如果您正在Windows上寻找解决方案,Powershell具有读取和写入XML的内置功能

test.xml:

<root>
  <one>I like applesauce</one>
  <two>You sure bet I do!</two>
</root>

我喜欢苹果酱
我当然知道!
Powershell脚本:

# load XML file into local variable and cast as XML type.
$doc = [xml](Get-Content ./test.xml)

$doc.root.one                                   #echoes "I like applesauce"
$doc.root.one = "Who doesn't like applesauce?"  #replace inner text of <one> node

# create new node...
$newNode = $doc.CreateElement("three")
$newNode.set_InnerText("And don't you forget it!")

# ...and position it in the hierarchy
$doc.root.AppendChild($newNode)

# write results to disk
$doc.save("./testNew.xml")
#将XML文件加载到局部变量并强制转换为XML类型。
$doc=[xml](获取内容。/test.xml)
$doc.root.one#呼应“我喜欢苹果酱”
$doc.root.one=“谁不喜欢苹果酱?”#替换节点的内部文本
#创建新节点。。。
$newNode=$doc.CreateElement(“三”)
$newNode.set_InnerText(“别忘了它!”)
#…并将其置于层次结构中
$doc.root.AppendChild($newNode)
#将结果写入磁盘
$doc.save(“./testNew.xml”)
testNew.xml:

<root>
  <one>Who likes applesauce?</one>
  <two>You sure bet I do!</two>
  <three>And don't you forget it!</three>
</root>

谁喜欢苹果酱?
我当然知道!
别忘了!
来源:

能够使用XPath 3.0/XQuery 3.0。(其他命令行工具使用XPath 1.0)

示例: http/html:

$ saxon-lint --html --xpath 'count(//a)' http://stackoverflow.com/q/91791
328
xml:


我首先使用了xmlstarlet,现在仍在使用它。当查询变得困难时,我需要XML的xpath2和xquery功能支持。我转向xidel。Bohdan维护了一个开源GitHub repo,其中保存了结构化文本工具的命令行工具列表,其中有一个XML/HTML工具部分:

Grep当量 您可以定义一个bash函数,比如“xp”(“xpath”),它封装了一些python3代码。要使用它,您需要安装python3和pythonlxml。好处:

  • 您在xmllint中缺少的正则表达式匹配
  • 用作命令行上的过滤器(在管道中)
  • 它使用起来简单且功能强大,如下所示:

    xmldoc=$(cat <<EOF
    <?xml version="1.0" encoding="utf-8"?>
    <job xmlns="http://www.sample.com/">programming</job>
    EOF
    )
    selection='//*[namespace-uri()="http://www.sample.com/" and local-name()="job" and re:test(.,"^pro.*ing$")]/text()'
    echo "$xmldoc" | xp "$selection"
    # prints programming
    
    xp()
    { 
    local selection="$1";
    local xmldoc;
    if ! [[ -t 0 ]]; then
        read -rd '' xmldoc;
    else
        xmldoc="$2";
    fi;
    python3 <(printf '%b' "from lxml.html import tostring\nfrom lxml import etree\nfrom sys import stdin\nregexpNS = \"http://exslt.org/regular-expressions\"\ntree = etree.parse(stdin)\nfor e in tree.xpath('""$selection""', namespaces={'re':regexpNS}):\n  if isinstance(e, str):\n    print(e)\n  else:\n    print(tostring(e).decode('UTF-8'))") <<< "$xmldoc"
    }
    

    xmldoc=$(cat难道你不能为Ruby程序创建一个包装器脚本,并将脚本中的参数数组传递给hpricot吗?例如,在PHP shell脚本中,类似以下的东西应该可以工作:@Joseph Holsten是的。它允许在不考虑XPath的情况下使用XML进行黑客攻击。很好!我一直在关注不使用中间层的工具E格式,但是对于XML来说,高保真、面向线的表示似乎是一种使用真正的GRIP和SED的好方法。您尝试过PyXY吗?它是如何比较的?任何其他的面向行的表示?您是否认为这比用实体替换XML新行更好?(&10);?这至少可以让你将记录粘贴在同一行上。哦,你能编辑你的帖子以包含项目链接吗?@Joseph Holsten不,我不认为pyxie格式比xml2格式更有用。xml2提供“完整路径”在嵌套的XML元素中,因此允许更多的面向行的匹配和替换。另外,
    2xml
    可以轻松地从部分(过滤的)
    xml2
    输出中重新创建XML。+1我无法对此进行足够的升级…
    cat foo.XML | xml2 | grep/bar | 2xml
    -为您提供与
    xmldoc=$(cat <<'EOF'
    <resources>
        <string name="app_name">Keep Accounts</string>
        <string name="login">"login"</string>
        <string name="login_password">"password:"</string>
        <string name="login_account_hint">input to login</string>
        <string name="login_password_hint">input your password</string>
        <string name="login_fail">login failed</string>
    </resources>
    EOF
    )
    echo "$xmldoc" | xq '.resources.string = ([.resources.string[]|select(."#text" == "Keep Accounts") ."#text" = "Keep Accounts 2"])' -x