3

I have a xml called Det.xml like this :

<?xml version="1.0" encoding="UTF-8"?>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
        <S:Body>
            <ns4:grtHgetRed xmlns:ns2="http://object" xmlns:ns3="http://object" xmlns:ns4="http://object">
                <RequestId>lol</RequestId>
                <MessageDateTime>54.009</MessageDateTime>
                <SenderId>UH</SenderId>
                <ReceiverId>GER</ReceiverId>
                <TrackingNumber>45</TrackingNumber>
                <ServerName>trewds</ServerName>
                <ResponseType>success</ResponseType>
                <StatusInfo>
                <Status>success</Status>
                <SystemMessage>Hagert</SystemMessage>
                <UserMessage>Hgert</UserMessage>
                <Origination>htref</Origination>
                </StatusInfo>
            </ns4:grtHgetRed>
        </S:Body>
    </S:Envelope>

I am trying to get the ResponseType node value success from it using xmllint in Unix shell script and so i tried the following :

echo "cat //*[local-name()='S:Envelope'/*[local-name()='S:Body']/*[local-name()='ns4:grtHgetRed']/*[local-name()='ResponseType']" | xmllint --shell Det
.xml | sed '/^\/ >/d' | sed 's/<[^>]*.//g'

But it's not working . Also i don't have xpath in my unix environment . Can any one tell me what am i doing wrong here ?

I also tried using statusMSG=="$(echo "cat /Envelope/Body/grtHgetRed/ResponseType/text()" | xmllint --nocdata --shell response.xml | sed '1d;$d')", then echo "$statusMSG", but this gives an empty echo. Is this because of namespace problem ?

The Dark Knight
  • 2,124
  • 4
  • 19
  • 20

2 Answers2

11

If your Det.xml is always going to look like that (e.g. won't have any extra ResponseType nodes), you can simply use this:

xmllint --xpath 'string(//ResponseType)' Det.xml

And it will spit out: success


If your xmllint doesn't have xpath for some reason, you can always fall back to regular expressions for this sort of thing:

grep -Po '(?<=<ResponseType>)\w+(?=</ResponseType>)' Det.xml

It uses Perl regular expressions to allow for the positive look aheads / look behinds and only shows the matched part (not the whole line). This will output the same as above without using xmllint / xpath at all.

Jay
  • 226
  • 2
  • 5
  • As I mentioned, i don't have `xpath` in the unix env . – The Dark Knight Sep 24 '13 at 13:41
  • Ah, I wasn't quite sure what you were referring to. I thought it was a standalone script that you didn't have or something. I assume you have grep? I'll update my answer with an alternative. – Jay Sep 24 '13 at 13:46
  • @TheDarkKnight I've posted a solution using only grep. It's crude, but it gets the job done. If you're looking for a pure xmllint solution I'll let someone else venture there. Best of luck. – Jay Sep 24 '13 at 13:53
  • Perfect , thanks a lot. That's what i wanted . Up voted and accepted . – The Dark Knight Sep 24 '13 at 14:02
  • Is it possible to stop xmllint --xpath from turning `ø` into `ø` etc. in id attributes? – unhammer Feb 06 '23 at 10:10
1

As you were looking for a solution using xmllint without --xmlpath Option, the following works for me:

echo "cat //ResponseType/text()" | xmllint --nocdata --shell /tmp/Det.xml | grep -v '/'
success

Your example statusMSG=="$(echo "cat /Envelope/Body/grtHgetRed/ResponseType/text()" | xmllint --nocdata --shell response.xml | sed '1d;$d')" does not work because you use the echo "cat .../text()" inside quotes without Quotation and you use the == Operator instead of an assignment.

stefan123t
  • 11
  • 1