Priyanshu Goyal
Priyanshu Goyal

Reputation: 342

Parse XML using xmllint displaying multiple keys

I have the following xml:

<suite>
<suite total="3" errors="2">
    <case class="abc" name="123">
        <error type="Error"></error>
    </case>
    <case class="abc" name="456">
    </case>
    <case class="abc" name="789">
        <error type="Error"></error>
    </case>
</suite>
<suite>
   ...
</suite>

I want to extract the information so that the final solution looks like this :

abc/123 abc/789

i.e. print the class/name if the error tag exists.

I have been able to get the class or the name separately using the command :

echo 'cat //suite[@errors!="0"]/case[error[@type="Error"]]/@name' | xmllint --shell <file-path>

Is there a way to get both class and name in the required format?

Upvotes: 1

Views: 467

Answers (2)

Priyanshu Goyal
Priyanshu Goyal

Reputation: 342

The final solution that i came up with was:

failed=$(echo 'cat //suite[@errors!="0"]/case[error[@type="Error"]]/@*' | xmllint --shell <file-path> | awk '{if (NR %3 != 0) print $1 }' | awk '/^[nc]/' | awk -F'[="]' '{print $(NF-1)}'| awk '{if (NR%2!=0) printf " -i " $1; else printf "/"$1}')

The actual format required was -i class/name

Also, the xml contained 3 attributes instead of 2 in the case tag (class,name,time)

Upvotes: 1

LMC
LMC

Reputation: 12822

It's not possible with xmllint and XPath 1.0 but can be done with a little help of bash

echo 'ls //suite[@errors!="0"]/case[error[@type="Error"]]/@*' | xmllint --shell test.xml | gawk '/^ta/{ print $3 }' | sed '$!N;s/\n/\//'

Result:

abc/123
abc/789

Basically, it's parsing the output of ls in xmllint shell

ta-        3 abc
ta-        3 123
ta-        3 abc
ta-        3 789

Upvotes: 1

Related Questions