Domanda

Questo è davvero un problema strano.Mi prese praticamente tutto il giorno, per whittle giù per un piccolo script eseguibile che viene illustrato il problema completamente.

Riepilogo Problema: Sto utilizzando XML::Twig per estrarre dati frammento da un file XML, quindi mi sto attaccando i dati frammento in mezzo un altro pezzo di dati, diciamo, padre di dati.I dati padre ha questo strano caratteri non stampabili, all'inizio, quando l'ho avviato.È fornito del fornitore di dati, quindi non posso controllare.Il mio problema è che dopo mi attengo ai dati frammento in mezzo il padre di dati, il prodotto finale ha una nuovo caratteri non stampabili, al suo inizio, oltre a quello che è iniziato con inizialmente.Questa nuova caratteri non stampabili, non era il padre di dati, né nel figlio di dati snippet.Non so da dove proviene e non come è sempre nel mio dati.

Sono dubbi che si tratta di un XML::Twig bug perché la stringa di corruzione si verifica durante la lettura di una riga da un filehandle in un ciclo while, ma sono riuscita a ricreare il mio problema quando ho rimosso il codice XML::Twig codice nel mio script, così ho dovuto lasciare.

Questa è la mia prima esperienza con caratteri non stampabili in stringhe che sto cercando di processo.Ho bisogno di fare qualcosa di speciale, invece di trattarli come stringhe normali o qualcosa del genere?

Sto usando ActiveState Perl 5.10.1 e XML::Twig 3.32 (l'ultima) e l'Eclisse 3.5.1 IDE Windows XP.

Questo è uno script che viene illustrato il problema:

use strict; 
use warnings; 
use XML::Twig; 

my $FALSE = 0;
my $TRUE = 1;
my $name = 'KurtsProgram';
my $task = 'MainTask';
my $hidden_char = "\xBF";
my $data = $hidden_char . 
'(*********************************************
  Data-File-Header-Junk
**********************************************)

    PROGRAM MainProgram ()
    END_PROGRAM

    TASK SecondaryTask ()
    END_TASK

    TASK MainTask ()
        MainProgram;
    END_TASK
';
my $new_data = insertProgram( $name, $task, $data );

# test to see if results start out as expected
if ( $new_data =~ m/^\Q$hidden_char\E/ ) {
    print "SUCCESS\n";
}
else {
    print STDERR "ERROR: What happened?\n";
    print STDERR "ORIGINAL: \n$data\n";
    print STDERR "MODIFIED: \n$new_data\n";
}

sub insertProgram {
    my ( $local_name, $local_task, $local_data ) = @_;

    # get program section from XML template
    my $twig = new XML::Twig;
    $twig->parse( '<?xml version="1.0"?>
<TemplateSet>
    <PROGRAM>PROGRAM <Name>ProgramNameGoesHere</Name> ()
    END_PROGRAM</PROGRAM>
    <TASK>TASK <Name>TaskNameGoesHere</Name> ()
    END_TASK</TASK>
</TemplateSet>
' );   
    my $program = $twig->root->first_child('PROGRAM');

    # replace program name in XML template
    $program->first_child('Name')->set_text($local_name);
    my $insert = $program->text();

    # stick modified program into data
    if ( $local_data =~ s/(\s+PROGRAM\s+[^\s]+\s+\()/\n\n    $insert $1/ ) {
        # found it and inserted new program
    }
    else {
        # not found
        return;
    }

    # add program name to task list
    my $added_program_to_task = $FALSE;
    my $found_start = $FALSE;
    my $found_end = $FALSE;
    my $new_data = "";
    # open string as a filehandle for line by line processing
    my $filehandle;
    open( $filehandle, '<', \$local_data )
        or die("Can't open string as a filehandle: $!");
    while (defined (my $line = <$filehandle>)) {
        # look for start of our task
        if ( 
               ( !$found_start ) &&
               ( $line =~ m/\s+TASK\s+\Q$local_task\E\s+\(/ )
            ) {
            # found the task!
            $found_start = $TRUE;
        }

        # look for end of our task
        if (
                ( $found_start ) && ( !$found_end ) &&
                ( $line =~ m/\s+END_TASK/ )
            )
        {
            # found the end tag for the task section!
            $found_end = $TRUE;

            # add the program name to the bottom of the list
            $line = "        " . $local_name . ";\n" . $line;
            $added_program_to_task = $TRUE;
        }

        # compile new data from processed line or original line
        $new_data = $new_data . $line;
    }
    close($filehandle);

    if ($added_program_to_task) {
        # success
    }
    else {
        # unable to find task
        return;
    }

    return $new_data;
}

Quando eseguo questo script, ottengo il seguente output:

ERROR: What happened?
ORIGINAL: 
¿(*********************************************
      Data-File-Header-Junk
    **********************************************)

        PROGRAM MainProgram ()
        END_PROGRAM

        TASK SecondaryTask ()
        END_TASK

        TASK MainTask ()
            MainProgram;
        END_TASK

MODIFIED: 
¿(*********************************************
      Data-File-Header-Junk
    **********************************************)

        PROGRAM KurtsProgram ()
        END_PROGRAM 

        PROGRAM MainProgram ()
        END_PROGRAM

        TASK SecondaryTask ()
        END_TASK

        TASK MainTask ()
            MainProgram;
            KurtsProgram;
        END_TASK

Si può vedere il carattere aggiuntivo che è stato aggiunto a fronte di dati a destra sotto la M MODIFICATI.

È stato utile?

Soluzione

Ha fatto un ISO-8859-1 a UTF-8 codifica di conversione sul personaggio: \xBF -> \xC2\xBF.

XML::Twig converte tutti il suo ingresso in UTF-8 (vedi qui).

Si potrebbe dire Twig per mantenere la codifica di input utilizzando il keep_encoding opzione (vedi anche il XML::Twig FAQ: Il mio XML documenti/dati sono prodotte da strumenti che non grok Unicode, si XML::Twig aiutatemi vi?).

Ma forse sarebbe meglio tenere la codifica UTF-8, o forse elimina automaticamente il carattere, a seconda di che cosa esattamente si sta andando a che fare con esso.

Altri suggerimenti

Non posso davvero dare un senso del codice, è ancora troppo complesso per essere rapidamente il debug, ma forse il problema ha a che fare con un BOM (vedere la Unicode BOM FAQ ) che sarebbe stato ignorato all'inizio di un documento XML, ma non se lo si copia nel bel mezzo di un altro? solo indovinando qui a causa del valore XBF, questo fa parte della distinta base per un documento UTF-8.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top