2016-12-16 5 views
0

ich eine XML-Datei haben enthalten Daten wie:regex für Dateioperation in Perl nicht funktioniert

<get>9090</get><br> 
<setId>setIdHere</set> 
<mainId>121</mainId> 

Da ich keine externe lib/Pakete verwenden, aber ich bin brauchen einige Änderungen muss ich mit /O.

Ich muss die Zeichenfolge setIdHere mit something ändern. Sie finden den Perl-Code unten:

my $filename="file1.xml"; 
my $idVal=3232; 
open(my $fh , '>>' ,$fileName); 
select $fh or die $!; 
s/setIdHere/$idVal; 
print; 
select STDOUT; 
close($fh); 

Der obige Code den Wert am Ende ist, anhängt, aber ich will setIdHere es mit der Zeichenfolge ersetzen.

Ich bin neu zu Perl nicht sicher, was mit dem obigen Code falsch ist.

Vielen Dank im Voraus.

+0

Ihr Code nicht kompiliert. Es liest auch nie die Datei. Kannst du den echten Code kopieren und hinterher? – Schwern

Antwort

2

Bitte, never ever use regular expressions to parse XM L. XML ist kontextabhängig, und reguläre Ausdrücke sind nicht. Daher ist es nur jemals wird ein schmutziger Hack sein.

Ich würde XML::Twig empfehlen, wenn Sie eine XML-Datei ändern müssen. Es unterstützt xpath, die wie regulären Ausdrücken ist, aber inhärent behandelt das Kontextproblem.

XML::Twig hat auch 'parsefile_inplace' für das Editieren der Datei:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use XML::Twig; 

sub modify_setId { 
    my ($twig, $setId) = @_; 
    $setId -> set_text('3232'); 
    $twig -> flush; 
} 

my $twig = XML::Twig -> new (twig_handlers => { 'setId' => \&modify_setId }); 
$twig -> set_pretty_print('indented'); 
$twig -> parsefile_inplace('test.xml'); 
3

Zunächst einmal verwendet Ihr Code einige ungewöhnlich veraltete Techniken. select $fh hat einen globalen Effekt und wird am besten vermieden.

Um eine Datei bearbeiten zu können, müssen Sie sie zum Lesen öffnen, einlesen, ändern und wieder zurückschreiben. Um zu vermeiden, dass die gesamte Datei in den Speicher gezogen wird, kann die Datei sehr groß sein. Dies geschieht im Allgemeinen Zeile für Zeile.

Sie können nicht in die gleiche Datei schreiben, aus der Sie lesen (naja, Sie können, aber es macht ein Durcheinander), also schreiben Sie stattdessen in eine temporäre Datei und wenn Sie fertig sind, benennen Sie sie um Original.

# This forces you to declare all variables protecting against typos 
use strict; 
# This lets you know when you've done something you probably shouldn't. 
use warnings; 
# This will error if file operations failed, no more "or die $!" 
use autodie; 

my $file = "file1.xml"; 
my $tmp = $file.".new"; # file1.xml.new 

open my $in, "<", $file; # open the XML file for reading 
open my $out, ">", $tmp; # open a temp file for writing 

# Read the file line by line 
while(my $line = <$in>) { 
    # Change the line. 
    $line =~ s{this}{that}g; 

    # Write it to the temp file. 
    print $out $line; 
} 

# If you don't do this, it might not have finished writing. 
close $out; 
close $in; 

# Overwrite the old file with the new one. 
rename $temp, $file; 

JEDOCH Sie bearbeiten XML. XML ist strukturiert und Sie sollten nicht versuchen, es mit Regexes zu lesen und zu bearbeiten. Sie müssen es stattdessen mit einer XML-Bibliothek wie XML::LibXML oder analysieren.

Sie sagen, Sie können keine externe Bibliothek verwenden, aber ich wette, Sie können, es ist nur eine Frage der herauszufinden, wie. Sie werden es viel einfacher haben, wenn Sie es tun. Im Allgemeinen ist der Grund, dass Sie keine Administratorrechte haben. Die einfachste Lösung ist die Installation von perlbrew und die Installation einer eigenen Perl-Version, die Sie verwalten können. Perlbrew macht das einfach.

+0

Bitte empfehlen Sie nicht "XML :: Simple" (http://stackoverflow.com/questions/33267765/why-is-xmlsimple-discouraged) - sogar die Dokumentation dafür schlägt vor, etwas anderes zu verwenden. 'XML :: LibXML' und' XML :: Twig' sind beide eine viel bessere Wahl. – Sobrique

+0

@Sobrique Okie Doke. – Schwern