Find and execute math expression from xml attribute and replace value

The following is a snippet of some XML files that need processing:

<BirimAdi>Adet</BirimAdi> <BirimCarpan>1</BirimCarpan> <HavaleFiyati>0</HavaleFiyati> <HavaleFiyatiParaBirimi>TL</HavaleFiyatiParaBirimi> <Price1>0</Price1> <SatisFiyati1ParaBirimi>TL</SatisFiyati1ParaBirimi> <Isk1>0</Isk1> <SatisFiyati2>0</SatisFiyati2> 

What I need to do is take the value between the tags and perform the following mathematical operation on it.

 Price1 = round(Price1)-0.1; 

The script should do this with all xml files at the specified path.

I have considered using 'sed' or 'awk', but I'm not sure if this can be done easily in sed. Using xmllint overwhelmed me too much. Any ideas? I am new to these utilities, so I could not count on the fact that the regular expression that will find the bit I'm looking for is:

 /<\s*Price1[^>]*>([^<]*)<\s*\/\s*Price1\s*>/ 
+4
source share
2 answers

I would use an XML parser for the job. For example, XML::Twig . Here is an example:

 #!/usr/bin/env perl use warnings; use strict; use XML::Twig; for my $f ( @ARGV ) { my $twig = XML::Twig->new( twig_handlers => { 'Price1' => sub { $_->set_text( sprintf( "%.1f", int( $_->text) - 0.1 ) ) }, }, pretty_print => 'indented', )->parsefile( $f )->print; } 

Assuming the script.pl file script.pl and the test xmlfile with content:

 <root> <BirimAdi>Adet</BirimAdi> <BirimCarpan>1</BirimCarpan> <HavaleFiyati>0</HavaleFiyati> <HavaleFiyatiParaBirimi>TL</HavaleFiyatiParaBirimi> <Price1>3.3</Price1> <SatisFiyati1ParaBirimi>TL</SatisFiyati1ParaBirimi> <Isk1>0</Isk1> <SatisFiyati2>0</SatisFiyati2> </root> 

Run it like this:

 perl script.pl xmlfile 

This gives:

 <root> <BirimAdi>Adet</BirimAdi> <BirimCarpan>1</BirimCarpan> <HavaleFiyati>0</HavaleFiyati> <HavaleFiyatiParaBirimi>TL</HavaleFiyatiParaBirimi> <Price1>2.9</Price1> <SatisFiyati1ParaBirimi>TL</SatisFiyati1ParaBirimi> <Isk1>0</Isk1> <SatisFiyati2>0</SatisFiyati2> </root> 
+7
source

Quick dirty solution:

 perl -pe 's!<(Price1)>(\d+(?:\.\d*)?)</\1>!"<$1>".(int($2+0.5)-0.1)."</$1>"!e'<<XXX <HavaleFiyatiParaBirimi>TL</HavaleFiyatiParaBirimi> <Price1>2.3</Price1> <SatisFiyati1ParaBirimi>TL</SatisFiyati1ParaBirimi> <Price1>2.5</Price1> XXX 

Output:

 <HavaleFiyatiParaBirimi>TL</HavaleFiyatiParaBirimi> <Price1>1.9</Price1> <SatisFiyati1ParaBirimi>TL</SatisFiyati1ParaBirimi> <Price1>2.9</Price1> 

But the Birei solution is better today ...

+1
source

Source: https://habr.com/ru/post/1481375/


All Articles