【问题标题】:How to grep an xml block in an xml file using a keyword如何使用关键字 grep xml 文件中的 xml 块
【发布时间】:2015-06-02 10:36:51
【问题描述】:

我有一个文件 Sample.xml,其中包含很多服务 结构是这样的

问题: 输入:队列名称 输出:服务块

样本 输入:ABC.getme2

输出:

<service name="GETME2" min="1" max="10" idleTime="300" backend="ABC">
                            <handlerContainer className="com.abc.xyz.wqere.abcqwere">
                            <handler className="com.abc.xyz.qweqweqwe.werwerwerwer"/>
                            </handlerContainer>
                            <mqListener queue="ABC.getme2" suggExpiry="30" minExpiry="4" maxExpiry="500" copyMessageId="true"/>
                    </service>

XML 结构:

     <?xml version="1.0" encoding="UTF-8"?>
        <deploymentconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <configfile>sample.xml</configfile>
                <exceptionsFilterConfigFile>asdasd.xml</exceptionsFilterConfigFile>
                <keyInfoConfigFile>asdasd.xml</keyInfoConfigFile>
                <services>

    <service name="GETME" min="1" max="10" idleTime="300" backend="ABC">
                            <handlerContainer className="com.abc.xyz.wqere.abcqwere">
                            <handler className="com.abc.xyz.qweqweqwe.werwerwerwer"/>
                            </handlerContainer>
                            <mqListener queue="ABC.getme" suggExpiry="30" minExpiry="4" maxExpiry="500" copyMessageId="true"/>
                    </service>

    <service name="GETME2" min="1" max="10" idleTime="300" backend="ABC">
                            <handlerContainer className="com.abc.xyz.wqere.abcqwere">
                            <handler className="com.abc.xyz.qweqweqwe.werwerwerwer"/>
                            </handlerContainer>
                            <mqListener queue="ABC.getme2" suggExpiry="30" minExpiry="4" maxExpiry="500" copyMessageId="true"/>
                    </service>
        . . . .a lot of services like this . . . .
        . . . .a lot of services like this . . . .
        . . . .a lot of services like this . . . .
        . . . .a lot of services like this . . . .
        </services>
   <batchServices>
                        <batchService name="batch1">
                                <executor className="com.abc.xyz.qwer.qweqwewqe.ffdsdfsdfsdfsdf" />
                        </batchService>
                        <batchService name="batch2">
                                <executor className="com.abc.xyz.qwer.qweqwewqe.zxcsadsad" />
                        </batchService>
. . . .a lot of batch services like this . . . .
        . . . .a lot of batch services like this . . . .
        . . . .a lot of batch services like this . . . .
        . . . .a lot of batch services like this . . . .
      </batchServices>

<timerservices>
<timerservice> - a lot of timeservice
</timerservices>

  <connectionPools>
                <pool>
                        <name>asdasd</name>
                        <driver>oracle.jdbc.driver.OracleDriver</driver>
                        <url>$asdasd_URL</url>
                        <userId>$asdasd_USER</userId>
                        <password>$asdasd_PASSWORD</password>
                        <minConnections>0</minConnections>
                        <maxConnections>10</maxConnections>
                        <poolUrl>jdbc:asdsad:asdasdsad</poolUrl>
                        <testSql>select * from abc</testSql>
                </pool>

 . . a lot of pools. . .

</connectionpools>

</deploymentconfig>

我需要像这样 grep 一个 xml 块:

 <service name="GETME" min="1" max="10" idleTime="300" backend="ABC">
                        <handlerContainer className="com.abc.xyz.wqere.abcqwere">
                        <handler className="com.abc.xyz.qweqweqwe.werwerwerwer"/>
                        </handlerContainer>
                        <mqListener queue="ABC.getme" suggExpiry="30" minExpiry="4" maxExpiry="500" copyMessageId="true"/>
                </service>

我只需要提供队列名称

QUEUENAME=INSERT_HERE
grep ______________ $QUEUENAME. . . 

我尝试了下面的答案

xmllint --xpath '//service[@name="GETME"]' Sample.xml

xmllint --xpath '/services/service[@name="GETME"]' Sample.xml

xmlstarlet sel -t -v "/services/service[@name='GETME']/mqListener/@queue" Sample.xml

但没有成功

这是输出:

Usage : xmllint [options] XMLfiles ...
    Parse the XML files and output the result of the parsing
    --version : display the version of the XML library used
    --debug : dump a debug tree of the in-memory document
    --shell : run a navigating shell
    --debugent : debug the entities defined in the document
    --copy : used to test the internal copy implementation
    --recover : output what was parsable on broken XML documents
    --noent : substitute entity references by their value
    --noout : don't output the result tree
    --path 'paths': provide a set of paths for resources
    --load-trace : print trace of all external entites loaded
    --nonet : refuse to fetch DTDs or entities over network
    --nocompact : do not generate compact text nodes
    --htmlout : output results as HTML
    --nowrap : do not put HTML doc wrapper
    --valid : validate the document in addition to std well-formed check
    --postvalid : do a posteriori validation, i.e after parsing
    --dtdvalid URL : do a posteriori validation against a given DTD
    --dtdvalidfpi FPI : same but name the DTD with a Public Identifier
    --timing : print some timings
    --output file or -o file: save to a given file
    --repeat : repeat 100 times, for timing or profiling
    --insert : ad-hoc test for valid insertions
    --compress : turn on gzip compression of output
    --html : use the HTML parser
    --xmlout : force to use the XML serializer when using --html
    --push : use the push mode of the parser
    --memory : parse from memory
    --maxmem nbbytes : limits memory allocation to nbbytes bytes
    --nowarning : do not emit warnings from parser/validator
    --noblanks : drop (ignorable?) blanks spaces
    --nocdata : replace cdata section with text nodes
    --format : reformat/reindent the input
    --encode encoding : output in the given encoding
    --dropdtd : remove the DOCTYPE of the input docs
    --c14n : save in W3C canonical format (with comments)
    --exc-c14n : save in W3C exclusive canonical format (with comments)
    --nsclean : remove redundant namespace declarations
    --testIO : test user I/O support
    --catalogs : use SGML catalogs from $SGML_CATALOG_FILES
                 otherwise XML Catalogs starting from 
             file:///etc/xml/catalog are activated by default
    --nocatalogs: deactivate all catalogs
    --auto : generate a small doc on the fly
    --xinclude : do XInclude processing
    --noxincludenode : same but do not generate XInclude nodes
    --loaddtd : fetch external DTD
    --dtdattr : loaddtd + populate the tree with inherited attributes 
    --stream : use the streaming interface to process very large files
    --walker : create a reader and walk though the resulting doc
    --pattern pattern_value : test the pattern support
    --chkregister : verify the node registration code
    --relaxng schema : do RelaxNG validation against the schema
    --schema schema : do validation against the WXS schema
    --schematron schema : do validation against a schematron
    --sax1: use the old SAX1 interfaces for processing
    --sax: do not build a tree but work just at the SAX level

Libxml project home page: http://xmlsoft.org/
To report bugs or get some help check: http://xmlsoft.org/bugs.html

这是版本

xmllint: using libxml version 20626

【问题讨论】:

  • ...所以,您没有支持 XPath 的 xmllint,也没有 xmlstarlet -- 我们真的需要知道您做什么拥有(最近的 Python,也许?),然后我们才能获得更多帮助。
  • 我看到了一些在 awk 和 sed 中完成的 XML 解析。这可以使用这些命令来完成吗?我真的不确定我有什么有用的东西。 xmllint 和 xmlstarlet 是最好的选择 - stackoverflow.com/questions/15879169/…
  • 不,awksed 不足以完成任务。另见stackoverflow.com/questions/1732348/…——它从关于语言理论的(准确)陈述开始。诚然,awk 比 BRE 更具表现力,理论上可以在 awk 中编写 XML 解析器,但是 - 与任何其他 XML 解析器一样 - 这将是构建和测试的主要项目;大型 XML 操作库需要以人为单位的努力才能达到完全合规性。
  • 您可以使用 awk 创建一些看起来可以运行一段时间的东西,但是如果加上命名空间、cmets、CDATA 部分,您很快就会开始遇到错误。使用适当的 XML 解析器,您会得到真正保证做正确的事。
  • 也就是说——任何现代平台都将包含 Python 解释器和适当的 XML 解析器。从 shell 调用 Python 真的没那么难。

标签: xml shell unix xpath xmllint


【解决方案1】:

命令几乎是正确的,你只需要修复 XPATH 表达式:

xmllint --xpath '//service[@name="GETME"]' Sample.xml
                          \ no slash hare

但是,您必须检查您的 xmllint 是否真的支持 XPATH:

$ xmllint --version
xmllint: using libxml version 20902
   compiled with: Threads Tree Output Push Reader Patterns Writer
   SAXv1 FTP HTTP DTDValid HTML Legacy C14N Catalog XPath XPointer
   XInclude Iconv ISO8859X Unicode Regexps Automata Expr Schemas
   Schematron Modules Debug Zlib Lzma 

【讨论】:

  • 有什么区别?您的原始示例具有正确的选项和文件顺序。
  • 我不知道。我添加了堆栈跟踪,似乎 xpath 不存在
  • 根据堆栈跟踪,推荐使用中不存在 xpath
  • 可能是 xmllint 的旧版本。顺便说一句,提供的文本不是 堆栈跟踪,请参阅en.wikipedia.org/wiki/Stack_trace
  • xmllint:使用 libxml 版本 20626
【解决方案2】:

为此目的的替代工具是XMLStarlet

xmlstarlet sel -t -c '//service[@name="GETME"]' -n <Sample.xml

顺便说一句,xmlstarlet 也可以输出 XSLT,您可以使用 xsltproc 应用它,因此在没有安装 xmlstarlet 的系统上。在这种情况下:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="yes" indent="no"/>
  <xsl:template match="/">
    <xsl:copy-of select="//service[@name=&quot;GETME&quot;]"/>
    <xsl:value-of select="'&#10;'"/>
  </xsl:template>
</xsl:stylesheet>

【讨论】:

  • -ksh: xmlstarlet: not found [No such file or directory]。而且我只处于阅读模式=(
  • 显然,您需要安装一个工具才能使用它。
  • 我没有安装工具的权限。还有其他方法吗?
猜你喜欢
  • 1970-01-01
  • 2012-04-15
  • 2020-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-16
  • 2015-11-01
相关资源
最近更新 更多