1

I have xml file including this:

<init-param>
    <param-name>listings</param-name>
    <param-value>true</param-value>
</init-param>
<init-param>
    <param-name>showServerInfo</param-name>
    <param-value>false</param-value>
</init-param>

what I need is to find two lines listings & true and replace it with listings & false

All I come up with was

sed -i 's/^<param-name>listings<\/param-name>\n<param-value>true<\/param-value>$/<param-name>listings<\/param-name><param-value>false<\/param-value>/g' somefile.xml

Thanks for any suggestion.

Marek Klement
  • 51
  • 1
  • 1
  • 4

2 Answers2

3

For the input file:

$ more input.xml
<root>
        <init-param>
            <param-name>listings</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>showServerInfo</param-name>
            <param-value>false</param-value>
        </init-param>
</root>

You can use the following XSLT stylesheet:

$ more listing_conv.xslt 
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="//init-param[./param-name = 'listings']/param-value">
        <param-value>false</param-value>
    </xsl:template>
</xsl:stylesheet>

Explanation:

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

this part will copy everything in the XML file (default behavior) except when you reach the XPATH: //init-param[./param-name = 'listings']/param-value

    <xsl:template match="//init-param[./param-name = 'listings']/param-value">
        <param-value>false</param-value>
    </xsl:template>

This second part will allow you to change the value of param-value to false.

As the XPATH will access elements whose name is init-param that have a child called param-name whose value is set at listings. For those elements you access the child element called param-value and overwrite it to false.

OUTPUT:

$ xsltproc listing_conv.xslt input.xml 
<?xml version="1.0"?>
<root>
  <init-param>
    <param-name>listings</param-name>
    <param-value>false</param-value>
  </init-param>
  <init-param>
    <param-name>showServerInfo</param-name>
    <param-value>false</param-value>
  </init-param>
</root>

I have used xsltproc command to run a XSLT proc but you can use other commands as xalan or you can just download a saxon parser jar: saxon9he.jar and run java -jar saxon9he.jar <attributes>

More info:

I need a simple command line program to transform XML using an XSL Stylesheet

Allan
  • 12,117
  • 3
  • 27
  • 51
0

I found a solution. I was not able to use XSLT or others. What solved my problem was simple awk. Your answers were really great and useful, for sure better than my solution, but I needed it this way.

awk -i inplace '{
    if ($0 ~ /globaltag/) {
        r=1
    }
    if ($0 ~ /listings/) {
        if (r==1) {
            s=1
        }
    } else {
        if($0 ~ /true/) {
            if(s==1){ 
                sub(/true/,"false");
                s=0
                r=0
            }
        } else {
            s=0
        }
    }
    print;
}' file.xml
Marek Klement
  • 51
  • 1
  • 1
  • 4