2009-01-15 19 views

Respuesta

4

Si está en una caja con el comando xsltproc, le sugiero que use XSLT para esto.

Para una solución de Perl iría por usar el DOM. Consulte este artículo DOM Processing with Perl.

Dicho eso. Si el archivo XML se produce de una manera algo predecible ingenua como la siguiente podría funcionar:

perl -pe 's#(<VALUE DECIMAL_VALUE=")([0-9.]+)(" UNIT_TYPE="percent"/>)#"$1" . ($2 + 0.4) . "$3"#e;' 
+0

Creo que quieres decir "($ 2 + 0,4)" no "($ 2 * 0,4)". –

+0

Sí, soy estúpido. Lo arreglaré de inmediato. – PEZ

0

Algo similar a lo siguiente funcionará. Puede necesitar ajustes si hay espacio adicional, pero eso se deja como un ejercicio para el lector.

function update_after(in_string, locate_string, delta) { 
    local_pos = index(in_string,locate_string); 
    leadin = substr(in_string,0,local_pos-1); 
    leadout = substr(in_string,local_pos+length(locate_string)); 
    new_value = leadout+delta; 
    quote_pos = index(leadout,"\""); 
    leadout = substr(leadout, quote_pos + 1); 
    return leadin locate_string new_value"\"" leadout; 
} 

/^ *\<VALUE/{ 
    print update_after($0, "DECIMAL_VALUE=\"",0.4); 
} 
2

Esta toma de entrada de la entrada estándar, salida estándar:

while(<>){ 
if($_ =~ /^(.*DECIMAL_VALUE=\")(.*)(\".*)$/){ 
    $newVal = $2 + 0.04; 
    print "$1$newVal$3\n"; 
}else{ 
    print $_; 
} 
} 
3

Si está absolutamente seguro de que el formato de su XML nunca cambiará, que el orden de los atributos es fijo, que efectivamente puede obtener la expresión regular para el número correcto ... luego opte por la solución no basada en el analizador.

Personalmente, utilizaría XML :: Twig (tal vez porque lo escribí; -). Procesará el XML como XML, sin dejar de respetar el formato original del archivo, y no lo cargará todo en la memoria antes de comenzar a trabajar.

código no probado a continuación:

#!/usr/bin/perl 
use strict; 
use warnings; 

use XML::Twig; 

XML::Twig->new(# call the sub for each VALUE element with a DECIMAL_VALUE attribute 
       twig_roots => { 'VALUE[@DECIMAL_VALUE]' => \&upd_decimal }, 
       # print anything else as is 
       twig_print_outside_roots => 1, 
      ) 
     ->parsefile_inplace('foo.xml'); 

sub upd_decimal 
    { my($twig, $value)= @_; # twig is the XML::Twig object, $value the element 
    my $decimal_value= $value->att('DECIMAL_VALUE'); 
    $decimal_value += 0.4; 
    $value->set_att(DECIMAL_VALUE => $decimal_value); 
    $value->print; 
    } 
+0

Hola, he estado trabajando en proyectos que dependen en gran medida de Twig. ¡Muchas gracias por escribir un módulo tan excelente! – PEZ

+0

Thanks.I womder si XML :: Twig es para XSLT lo que Perl es para LISP (vea http://xkcd.com/224/) – mirod

+0

Puede ser. Puede ser. =) – PEZ

0

aquí de gawk

awk '/DECIMAL_VALUE/{ 
for(i=1;i<=NF;i++){ 
    if($i~/DECIMAL_VALUE/){ 
     gsub(/DECIMAL_VALUE=|\042/,"",$i) 
     $i="DECIMAL_VALUE=\042"$i+0.4"\042" 
    } 
} 
}1' file 
Cuestiones relacionadas