Forum Discussion

vpachpute1's avatar
vpachpute1
Frequent Contributor
8 years ago
Solved

Groovy Script: XmlNodePrinter adds one extra line while writing into xml file.

Hi

 

Actually I want to write parameter value into xml file. It writes values perfectly but adds one extra line. Following is my groovy script. Can you please provide solution on same.

 

def filePath = '/home/vishalpachpute/API/Requests/AddUG.xml' 
def xml = new XmlParser().parse(new FileInputStream(new File(filePath)))
xml.get('payload').getAt('modify-usergroup').getAt('charging-id')[0].value = context.expand('${#TestCase#MSISDN_GB}')
new XmlNodePrinter(new PrintWriter(preserveWhitespace:false(new FileWriter(filePath)))).print(xml)

 

My Basic External xml request file (In this file I want to write charging-id value )

<abc-request client-application-id="JUnit client" client-domain="JUnit client Domain">
    <payload>
        <modify-UG>
            <charging-id type="msisdn">${#Project#MSISDN}</charging-id>
         </modify-UG>
    </payload>
</abc-request>

 

After writing property value first time: (Added one extra line)

<abc-request client-application-id="JUnit client" client-domain="JUnit client Domain">
    <payload>
        <modify-UG>
            <charging-id type="msisdn">
        447717148597
      </charging-id>
         </modify-UG>
    </payload>
</abc-request>

 

After writing property value Second time : (Added 2 extra lines)

<abc-request client-application-id="JUnit client" client-domain="JUnit client Domain">
    <payload>
        <modify-UG>
            <charging-id type="msisdn">
       

       447717148597


      </charging-id>
         </modify-UG>
    </payload>
</abc-request>

 

Regards

Vishal

  • nmrao's avatar
    nmrao
    8 years ago

    In that case, I would suggest the following:

    Have the original file with data as below which uses property expansion as mentioned earlier, you may call it template request.

    <abc-request client-application-id="JUnit client" client-domain="JUnit client Domain">
        <payload>
            <modify-UG>
                <charging-id type="msisdn">${#TestCase#MSISDN}</charging-id>
             </modify-UG>
        </payload>
    </abc-request>

     

    Before your json step, have a groovy step which does the transformation of the data and saves into a file in the temporary directory by replacing the MSISDN value. 

     

    This way, we always only read the template file(remains same) and create a new temporary file and that is sent as attachment each time. So, no overwriting of that template file.

     

    def tmp = System.getProperty('java.io.tmpdir')
    context.testCase.setPropertyValue('FINAL_DIR', tmp)
    def originalFilePath = context.expand('${#TestCase#ORIGINAL_FILE_PATH}')
    def fileName = context.expand('${#TestCase#FINAL_FILE}')
    def content = new File(originalFilePath).text
    new File("${tmp}/${fileName}").write(context.expand(content))

    Note: If you are using ReadyAPI, then you may avoid additional groovy step, instead use Events feature, TestStep.beforeSubmit and have the above script in it

     

     

    In the attachment, you define the custom properties as below:

     

12 Replies

  • nmrao's avatar
    nmrao
    Champion Level 3
    What is your use case? The request with property expansion (project value ) should still work, right? Why do you want to replace value?
  • Radford's avatar
    Radford
    Super Contributor

    [Edit: There was a problem with duplicate post, see my reply below.]

  • Radford's avatar
    Radford
    Super Contributor

    [Edit: There was a problem with duplicate post, see my reply below.]

  • Radford's avatar
    Radford
    Super Contributor

    I agree with nmrao, do you really need to updating values when the property expansion should do the job.

     

    But addressing your question...

     

    I believe that it is the preserve white space setting that is causing your issue. See the following code based on you initial post, that I had in a Groovy Test step. This will produce two files when with the extra line breaks and one without:

     

    import groovy.xml.*
    import groovy.util.XmlParser
    
    def xmlText = '''<abc-request client-application-id="JUnit client" client-domain="JUnit client Domain">
        <payload>
            <modify-UG>
                <charging-id type="msisdn"></charging-id>
             </modify-UG>
        </payload>
    </abc-request>'''
    
    def xml = new XmlParser().parseText(xmlText)
    
    xml.get('payload').getAt('modify-UG').getAt('charging-id')[0].value = context.expand( '${#TestCase#MSISDN_GB}' )
    
    // Exhibits the Extra line breaks issue
    def filePath1 = '/home/vishalpachpute/API/Requests/AddUG1.xml' 
    def printWriter1 = new PrintWriter(new FileWriter(filePath1))
    def xmlNodePrinter1 = new XmlNodePrinter(printWriter1)
    xmlNodePrinter1.setPreserveWhitespace(false) 
    xmlNodePrinter1.print(xml)
    
    // Does NOT exhibit the extra line break issue
    def filePath2 = '/home/vishalpachpute/API/Requests/AddUG2.xml' 
    def printWriter2 = new PrintWriter(new FileWriter(filePath2))
    def xmlNodePrinter2 = new XmlNodePrinter(printWriter2)
    xmlNodePrinter2.setPreserveWhitespace(true) 
    xmlNodePrinter2.print(xml)

     

    This blog post:

     

    http://mrhaki.blogspot.co.uk/2012/10/groovy-goodness-pretty-print-xml.html

     

    Contains some very useful information about formatting XML data.

    • vpachpute1's avatar
      vpachpute1
      Frequent Contributor

      Hi

       

      Answer: Actually property expansion does it. It is right. But my project requirement is

       

      1. Keep base xml request file at any external location.

      2. Call it in the requests. Change some properties values.

      So that going forward, if there any changes in the requests, we have do maintenance in externalized file only. Not inside the scripts.

       

      Thanks very much for your solution. It really helped me.

      • nmrao's avatar
        nmrao
        Champion Level 3
        The external request file should have property expansion, that resolves all.