Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set the text value of a node using xpath

Tags:

bash

xml

xpath

Example XML:

<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>
<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>
</bookstore>

I am using xpath on my shell to try and change the text value of an xml node. I would like to change Harry Potter to Game of Thornes.

xpath test.xml "//bookstore/book/title/text()" 2>/dev/null

Will echo out Harry Potter to my terminal. Now is it possible to use xpath to change the value of the node from Harry Potter to Game of Thornes?

Thanks!

like image 858
gdoubleod Avatar asked Jan 16 '23 23:01

gdoubleod


1 Answers

XPath by itself cannot be used to modify XML documents. But the xmlstarlet command line utility can do it. Example:

xml ed -u "//book[1]/title" -v "Game of Thrones" bookstore.xml

Output:

<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
  <book>
    <title lang="eng">Game of Thrones</title>
    <price>29.99</price>
  </book>
  <book>
    <title lang="eng">Learning XML</title>
    <price>39.95</price>
  </book>
</bookstore>

Note: without [1] in the expression, the result would be:

<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
  <book>
    <title lang="eng">Game of Thrones</title>
    <price>29.99</price>
  </book>
  <book>
    <title lang="eng">Game of Thrones</title>
    <price>39.95</price>
  </book>
</bookstore>

The command above outputs the result to stdout. There is an option (-L or --inplace) that modifies the document in place:

xml ed -L -u "//book[1]/title" -v "Game of Thrones" bookstore.xml 

This option is not mentioned in the documentation for xmlstarlet 1.3.1, but it is shown when executing

xml ed --help
like image 198
mzjn Avatar answered Jan 25 '23 09:01

mzjn