2
votes

I have the following XML file :

<Configuration .... status="INFO" >
  <properties>
    <property name="logfile">/var/log/app.log</property>
    <property name="log-level">INFO</property>
  </properties>
</Configuration>

I'm trying to replace the INFO in the log-level property to DEBUG.

[root]# xmlstarlet edit --update "/Configuration/properties/property[@name='log-level']/@value" --value DEBUG test.xml
<?xml version="1.0"?>
<Configuration status="INFO">
  <properties>
    <property name="logfile">/var/log/app.log</property2>
    <property name="log-level">INFO</property>
  </properties>
</Configuration>

The output in stdout is exactly the same as the orig file, nothing is changed.

I tried to search for the XPath to make sure that I used the right one and it worked :

[root]# xmlstarlet sel -t -v "count(Configuration/properties/property[@name='log-level'])" test.xml
1

I tried also to change the @name instead of the @value and it worked.

What am I missing ? Why the output(in stdout) isn't changed ?

1
Use the following: xmlstarlet edit --inplace --update "/Configuration/properties/property[@name='log-level']" --value "DEBUG" test.xml - the /@value part in your XPath is not necessary. Also add the --inplace option (or it's shorthand equivalent -L) to edit the file inplace. If you want to exclude the xml declaration, i.e. <?xml version="1.0"?>, in the resultant file include the --omit-decl option (or it's shorthand equivalent -O) too, for example: xmlstarlet edit --inplace --omit-decl --update "/Configuration/properties/property[@name='log-level']" --value "DEBUG" test.xmlRobC
@RobC thanks for the help but I already found a solution and posted here..JeyJ
Sure, it was meant as a note for others, They may want to edit the file in place, and omit the xml declaration.RobC

1 Answers

2
votes

Input file :

<Configuration status="INFO" >
  <properties>
    <property name="logfile">/var/log/app.log</property2>
    <property name="log-level">INFO</property>
  </properties>
</Configuration>

to make sure that your XPATH is the right one you can use the following command :

[root@]# xmlstarlet el test.xml

    Configuration
    Configuration/properties
    Configuration/properties/property
    Configuration/properties/property

After you have chosen the right XPath, in order to change the value of the attribute, you need to run :

[root]# xmlstarlet edit --update "/Configuration/properties/property[@name='log-level']" --value "DEBUG" test.xml
<?xml version="1.0"?>
<Configuration status="INFO">
  <properties>
    <property name="logfile">/var/log/app.log</property2>
    <property name="log-level">DEBUG</property>
  </properties>
</Configuration>

No need to specify /@value like I did in the question. If you want to change the name of a specific attribute, you should specify /@attribute_name in the end of the XPath, for example :

[root]# xmlstarlet edit --update "/Configuration/properties/property[@name='log-level']/@name" --value "DEBUG" test.xml
<?xml version="1.0"?>
<Configuration status="INFO">
  <properties>
    <property name="logfile">/var/log/app.log</property2>
    <property name="DEBUG">INFO</property>
  </properties>
</Configuration>