0

I have a file Sample.xml which contains a lot of services inside it and the structure looks like this

PROBLEM: INPUT: QUEUE NAME OUTPUT: SERVICE BLOCK

sample INPUT: ABC.getme2

OUTPUT:

<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 Structure:

     <?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>

I need to grep an xml block like this:

 <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>

and I only need to provide the queue name

QUEUENAME=INSERT_HERE
grep ______________ $QUEUENAME. . . 

I tried the answer below

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

and

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

and

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

but was unsuccesful

Here is the output:

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

Here is the version

xmllint: using libxml version 20626
Philip Morris
  • 459
  • 1
  • 9
  • 26
  • ...so, you don't have an xmllint with XPath support available, you don't have xmlstarlet -- we'd really need to know what you *do* have (a recent Python, maybe?) before we could be much more help. – Charles Duffy Jun 02 '15 at 16:13
  • I've seen some XML parsing done in awk and sed. Can this be done using those commands? I am really not sure on what I have that can be useful. xmllint and xmlstarlet was the best choices - http://stackoverflow.com/questions/15879169/extract-data-from-xml-using-ksh-script – Philip Morris Jun 02 '15 at 16:22
  • No, `awk` and `sed` are not adequate to task. See also http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 -- it starts out with (accurate) statements about language theory. Granted, `awk` is more expressive than BREs, and in theory one could write an XML parser in awk, but -- like any other XML parser -- it would be a major project to build and test; big XML manipulation libraries require effort measured in man-years to reach full compliance. – Charles Duffy Jun 02 '15 at 16:27
  • You may be able to create something with awk that looks like it works for a little while, but throw in namespaces, comments, CDATA sections, and you'll start hitting bugs quickly. Use a proper XML parser, and you get something that's actually _guaranteed_ to Do The Right Thing. – Charles Duffy Jun 02 '15 at 16:30
  • That said -- any modern platform will include a Python interpreter with a proper XML parser included. Calling into Python from shell is really not that hard. – Charles Duffy Jun 02 '15 at 16:31
  • Why don't you look at one of the answers already showing you how in one of the many, many duplicates to this question? – Charles Duffy Jun 02 '15 at 16:33
  • BTW, do you have `xsltproc` installed? – Charles Duffy Jun 02 '15 at 16:34
  • -ksh: xsltproc: not found [No such file or directory] – Philip Morris Jun 02 '15 at 16:36
  • I got a little desperate and did this : awk '//' Sample.xml but I need the queue name as the input , not the service name – Philip Morris Jun 02 '15 at 19:32
  • You still haven't told me which version of Python, if any, is installed. I'd like to know that so I wouldn't be wasting my time in writing a Python-assisted implementation. – Charles Duffy Jun 02 '15 at 19:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/79459/discussion-between-charles-duffy-and-philip-morris). – Charles Duffy Jun 02 '15 at 19:57

2 Answers2

0

The command is almost right, you only have to fix the XPATH expression:

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

However, you have to check whether your xmllint actually supports XPATHs:

$ 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 
dlask
  • 8,776
  • 1
  • 26
  • 30
0

An alternate tool for the purpose is XMLStarlet:

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

Incidentally, xmlstarlet can also output XSLT which you can apply with xsltproc, and thus on systems without xmlstarlet installed. In this case:

<?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>
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441