Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select node by its text value in xmlstarlet

I am trying to extract the value of the 'Value' node, where the 'Key' node is 'state' within a bash shell:

<FrontendStatus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" serializerVersion="1.1">
<script/>
 <State>
  <String>
   ...
   ...
  </String>
  <String>
   ...
   ...
  </String>
  <String>
   <Key>state</Key>
   <Value>WatchingLiveTV</Value>
  </String>
  <String>
   <Key>studiolevels</Key>
   <Value>1</Value>
  </String>
  <String>
   ...
   ...
  </String>
  <String>
   ...
   ...
  </String>
 </State>
</FrontendStatus>

I can extract the value if I reference the node directly:

$ xmlstarlet sel -t -m '/FrontendStatus[1]/State[1]/String[31]' -v Value <status.xml
WatchingLiveTV

But I would like to select it by the value of the 'Key' node instead

like image 526
SingingDwarf Avatar asked Feb 27 '15 00:02

SingingDwarf


2 Answers

This XPath will select Value of a State based on its Key equalling state:

/FrontendStatus/State/String[Key='state']/Value

Or, in xmlstarlet:

$ xmlstarlet sel -t -m "/FrontendStatus/State/String[Key='state']" -v Value <status.xml

Will return WatchingLiveTV as requested.

like image 80
kjhughes Avatar answered Nov 15 '22 01:11

kjhughes


I was able to find that node using the following XPath:

/FrontendStatus/State/String[Value = 'WatchingLiveTV']/Value

Which will return:

<Value>WatchingLiveTV</Value>

Note you could also use:

//String[Value = 'WatchingLiveTV']/Value

Which is slightly smaller.

To select the Value element and parent/siblings, you could use:

//String[Value = 'WatchingLiveTV']

Which returns:

<String>
  <Key>state</Key>
  <Value>WatchingLiveTV</Value>
</String>

Edit

I just re-read your original question. You would like to select the XML based on the value of the Key node. You can do this using the above, but changing the predicate from Value to Key:

//String[Key = 'state']/Value

@kjhughes has put this into the syntax format you're after.

I hope that helps.

like image 1
Rastus7 Avatar answered Nov 15 '22 03:11

Rastus7