xmllinuxxsltawkgawk

Script to update xml value



I am trying to do update on xml file based on condition using AWK Script. Could anyone assist me on this?

students.xml

<students>
    <student>
        <stuId>1</stuId>
        <name>A</name>
        <mark>75</mark>
        <result></result>
    </student>
    <student>
        <stuId>2</stuId>
        <name>B</name>
        <mark>35</mark>
        <result></result>
    </student>
    <student>
        <stuId>1</stuId>
        <name>C</name>
        <mark>94</mark>
        <result></result>
    </student>
</students>

Code I tried so far

I am able to extract tag values using below code

BEGIN { RS="<[^>]+>" } 
{ print  RT, $0 }

This prints all the tag and values as expected.

I want to update the <result> tag as pass if marks > 40 else fail

Output

<students>
    <student>
        <stuId>1</stuId>
        <name>A</name>
        <mark>75</mark>
        <result>pass</result>
    </student>
    <student>
        <stuId>2</stuId>
        <name>B</name>
        <mark>35</mark>
        <result>fail</result>
    </student>
    <student>
        <stuId>1</stuId>
        <name>C</name>
        <mark>94</mark>
        <result>pass</result>
    </student>
</students>

Could any one assist me on this?


Solution

  • Don't try to parse XML with , instead use a real parser :

    warning the XML file is edited on the fly!

    With :

    #!/usr/bin/env perl
    # edit file.xml file in place
    use strict; use warnings;
    
    use XML::LibXML;
    
    my $xl = XML::LibXML->new();
    my $xml = $xl->load_xml(location => '/tmp/file.xml') ;
    
    for my $node ($xml->findnodes('//student/result')) {
        my $mark = $node->findnodes('../mark/text()')->string_value;
        $node->removeChildNodes();
        if ($mark > 40) {
            $node->appendText('pass');
        }
        else {
            $node->appendText('fail');
        }
    }
    
    $xml->toFile('/tmp/file.xml');
    

    Modified file :

    <?xml version="1.0"?>
    <students>
      <student>
        <stuId>1</stuId>
        <name>A</name>
        <mark>75</mark>
        <result>pass</result>
      </student>
      <student>
        <stuId>2</stuId>
        <name>B</name>
        <mark>35</mark>
        <result>fail</result>
      </student>
      <student>
        <stuId>1</stuId>
        <name>C</name>
        <mark>94</mark>
        <result>pass</result>
      </student>
    </students>