replace string in XML with sed

Greetings,
I have an XML : file.xml

<component>
       <name>abcd</name>
       <value>1234</value>
</component>

I am using sed to replace abcd with the desired value dynamically without knowing the actual value.

sed 's/<name>[-[:alnum:]./]\{1,\}<\/name>/<name>ijkl<\/name>/' file.xml > newfile.xml

I don't have any issues with this command in Linux but on Solaris machine, I am getting the error:

If I remove >[-[:alnum:]./]\{1,\} and put the actual value, it is fine. But I have do it dynamically as I use it within the script to replace the existing value with the given value.

Can somebody please advise.

Thanks,
Chiru

I am surprised it works anywhere, the command is garbled in at least one way. There are 4 / characters in your expression.

I'm not at a solaris box right now, but I'm pretty sure Solaris sed does not support [::] format expressions, so you would get more change from something like:

sed 's#<name>\([^<][^<]*\)</name>#<name>SOMETHING</name>#' file.xml

If you replace the whole line this should be suffice:

sed 's#<name>.*#<name>SOMETHING</name>#' file.xml

Regards

you should use a tool specifically for parsing XML, not sed. (although it still can be done)

Thanks Reborg/Franklin..both of them work, but am using Reborg's as the other one is changing in some other places where I don't need.

What will be the easiest way of XML parsing - in the sense that I can use as part of the shell script I have which does several other tasks as well.

Thanks,
Chiru

The least painful way depends on your other requirements. If the file is simple then simple line-oriented shell utilities you are familiar with should usually suffice. If you need to do anything which requires any real understanding of XML structures (nesting, sibling and similar relationships, conditionals etc) then it probably makes sense to get at least some introductory familiarity to some proper XML tool. There are several formalisms to choose from and many tools which implement them; personally, I've been able to get things done with xsltproc after the first shock of trying to understand what got into the heads of the people who came up with the specifications for this.

The best way of handling this type of problem is using XSLT and a stylesheet.

Here is a stylesheet (file.xsl) which will do what you want:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="NAME"/>

<xsl:template match="name">
    <name><xsl:value-of select="$NAME"/></name>
</xsl:template>

<xsl:template match="*|text()|@*">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

Assuming for the purpose of this example that you want to change "abcd" to "Finnbarr" and that you have xsltproc installed on your system, here is how you would do the transformation together with the resulting output:

$ xsltproc -param NAME "'Finnbarr'" file.xsl file.xml
<?xml version="1.0"?>
<component>
       <name>Finnbarr</name>
       <value>1234</value>
</component>
$

Note the double and single quotes around the vale of the NAME parameter. These are required.