I have an input xml file like below
INPUT FILE
<ReconSummary>
<entryName>Total Deep</entryName>
<Code>777</Code>
<License>L</License>
<Tran>H20</Tran>
<job>1234</job>
</ReconSummary>
<ReconSummary>
<entryName>Total Saurav</entryName>
<Code>666</Code>
<License>L</License>
<Tran>H20</Tran>
<job>1234</job>
</ReconSummary>
<ReconSummary>
<entryName>Total Ankur</entryName>
<Code>555</Code>
<License>L</License>
<Tran>H20</Tran>
<job>1234</job>
</ReconSummary>
I want to comment the tag if i find the pattern "Total Deep" so that the output file looks like below
OUTPUT
<!--<ReconSummary>
<entryName>Total Deep</entryName>
<Code>777</Code>
<License>L</License>
<Tran>H20</Tran>
<job>1234</job>
</ReconSummary>-->
<ReconSummary>
<entryName>Total Saurav</entryName>
<Code>666</Code>
<License>L</License>
<Tran>H20</Tran>
<job>1234</job>
</ReconSummary>
<ReconSummary>
<entryName>Total Ankur</entryName>
<Code>555</Code>
<License>L</License>
<Tran>H20</Tran>
<job>1234</job>
</ReconSummary>
Since i am new to shell scripting, can anyone help me out as to how i can apply this with the help of shell scripting?
1 Answer 1
It's easy to use an XML parsing tool like xmlstarlet
to delete bits of XML matching some particular XPATH pattern.
In this case, to delete all ReconSummary
nodes whose entryName
child node has the value Total Deep
, you would do
xmlstarlet ed -d '//ReconSummary[entryName = "Total Deep"]' file.xml >newfile.xml
... assuming your file is a well-formed XML file (which your example isn't since it lack as single top-level node).
However, to comment out a bit of XML is a bit trickier, and xmlstarlet
can't do it directly.
You can instead apply an XSL transformation which rewrites your XML.
Using an answer that I wrote to a similar question, the XSL transformation
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/|node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//ReconSummary[entryName = 'Total Deep']">
<xsl:text disable-output-escaping="yes"><!-- </xsl:text>
<xsl:copy-of select="."/>
<xsl:text disable-output-escaping="yes"> --></xsl:text>
</xsl:template>
</xsl:transform>
would insert the XML comment markers <!--
and -->
around every ReconSummary
node whose entryName
child node had the value Total Deep
.
You would apply this XSL transformation to your XML file using either of
xmlstarlet tr transform.xsl file.xml >newfile.xml
or
xsltproc transform.xsl file.xml >newfile.xml
where you file is file.xml
and the transformation is stored in transform.xsl
.
awk
. When you detect this tag, collect lines in an array until you reach <entryName>. If it contains Total Deep, write "<!--", then the lines from the array. Write the rest until you hit the closing tag, then write "-->". If it contains something else, do the same but omit the comment strings.