Mass Replacement in XML

4

Good morning!

I have a program that checks some signals, but in the code it is only indicated which signal should appear, so I must apply the specific information that must be checked. But manually doing these overrides takes a lot of time so I would like to overwrite them in bulk.

My current code:

<comment>Check sinal P1R#</comment>

Replace for:

<comment>P1R#</comment>
<capltestfunction title="RUN INSPECTION" name="RunInspection">
    <caplparam type="string" name="InspName" />
</capltestfunction>
<capltestfunction title="ADD IMAGE TO REPORT" name="AddInspectionImageToReport" />
<capltestfunction title="CHECK MESSAGE" name="CheckStepResultCameraText">
    <caplparam type="string" name="StepName">TM_IN023_1</caplparam>
    <caplparam type="string" name="ExpVal">STEP</caplparam>
    <caplparam type="int" name="ContainsExpVal" />
    <caplparam type="int" name="TolerateSimilarChars">1</caplparam>
</capltestfunction>

I could not replace it normally because the content is too long. I'm learning to program yet so I need a help!

Thank you!

    
asked by anonymous 09.08.2016 / 16:08

1 answer

2

Using regular expressions to do parsing and XML transformation is not a good idea . Your problem demands both. The tool to be used needs to first find tags comment within the original document and then replace them with the desired fragment (with dynamic variations depending on the content of the original tag ).

For this kind of transformation it is worth using a tool that can handle the idiosyncrasies of XML. The good old XSLT is usually enough for this sort of thing.

Here is a stylesheet that solves the problem of the question:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes" method="xml" />
<xsl:strip-space elements="*"/>
   <!-- Identity transform -->
   <xsl:template match="@* | node()">
      <xsl:copy>
         <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="comment">
       <comment><xsl:value-of select="substring-after(text(), 'Check sinal ')" /></comment>
       <capltestfunction title="RUN INSPECTION" name="RunInspection">
           <caplparam type="string" name="InspName" />
       </capltestfunction>
       <capltestfunction title="ADD IMAGE TO REPORT" name="AddInspectionImageToReport" />
       <capltestfunction title="CHECK MESSAGE" name="CheckStepResultCameraText">
           <caplparam type="string" name="StepName">TM_IN023_1</caplparam>
           <caplparam type="string" name="ExpVal">STEP</caplparam>
           <caplparam type="int" name="ContainsExpVal" />
           <caplparam type="int" name="TolerateSimilarChars">1</caplparam>
       </capltestfunction>
   </xsl:template>
</xsl:stylesheet>

See working in XSL Transform

The first four lines declare a stylesheet whose output is a well-formatted, indented XML with no unnecessary spaces between the elements.

The first template is the template identity that simply copies the original content to the output.

The second template - more specific than the first and therefore with higher priority - replaces tags comment with new fragments composed of:

  • Other tag comment containing the piece of text after the string Check Signal in the tag comment original:

    <comment><xsl:value-of select="substring-after(text(), 'Check sinal ')" /></comment>
    
  • From this example you can build more complex transformations without relying on regular expressions that become more and more fragile and inefficient as the complexity of the problem increases.

        
    09.08.2016 / 19:12