Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

language selection via libxml

by banzai (Initiate)
on Jan 20, 2014 at 09:32 UTC ( [id://1071286]=perlquestion: print w/replies, xml ) Need Help??

banzai has asked for the wisdom of the Perl Monks concerning the following question:

What I want to do is make my GUI startable in different languages. I would input a parameter when starting the gui (e.g. perl gui.pl english) and when initialising the widgets it would get the text from a xml file that looks like this:

<?xml version="1.0"?> <language> <english> <widget ID="1">input</widget> <widget ID="2">output</widget> </english> <deutsch> <widget ID="1">eingabe</widget> <widget ID="2">ausgabe</widget> </deutsch> </language>

in the text setting of widgets i call a function with the widget id as a parameter.

sub change_lang { my $id= shift; my $file='lang.xml'; my $result; my $parser = XML::LibXML->new(); my $tree = $parser->parse_file($file); $result=$tree->findnodes("/language/$language/widget[@ID="$id"]"); return $result; }

but that doesnt work ("global symbol @ID requires explicit package name"). I don't know how to get to the content of the xml with scalars in the findnodes path. how would i do this? If anyone has better ideas for implementing language change, I'd be open for it, too. I'm too much of a perl scrub.

Replies are listed 'Best First'.
Re: language selection via libxml
by McA (Priest) on Jan 20, 2014 at 09:40 UTC

    Hi,

    $result=$tree->findnodes("/language/$language/widget[@ID="$id"]");

    The @ID is interpreted by Perl as an array access. You have to escape the '@'.

    Best regards
    McA

      Also need to lose the quotes around $id
      "/language/$language/widget[\@ID=$id]"
      Update:
      Thanks to choroba's explanations and examples below, this only works by accident, i.e. only if $id is a number.

      Here are some different ways of doing it:

      "/language/$language/widget[\@ID='$id']" "/language/$language/widget[attribute::ID='$id']" qq|/language/$language/widget[\@ID="$id"]| qq|/language/$language/widget[\@ID='$id']| qq|/language/$language/widget[attribute::ID="$id"]| qq|/language/$language/widget[attribute::ID='$id']|
        Not really. String literals must be enclosed in quotes in XPath expressions, and XPath does not know Perl variables (unless you use XML::XSH2).
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: language selection via libxml (perlquote)
by Anonymous Monk on Jan 20, 2014 at 09:53 UTC

    If you add use diagnostics; it will print a more verbose error message explaining this scenario (there is no variabele @ID which you keyboarded into your string)

    string quoting/interpolation are explained in perlintro and Strings in Perl: quoted, interpolated and escaped

    You can simplify your xpaths, like this (untested , may contain typos)

    sub enumerate_languages { my( $xmltree ) = @_; my @nodes = $xmltree->findnodes( '/language' ); my @langs = map { $_->tagName } @nodes; return @langs; } sub get_language { my( $xmltree, $lang ) = @_; my @nodes = $xmltree->findnodes( "/language/$lang/*" ); my %pairs ; for my $node ( @nodes ){ $pairs{ $node->getAttribute('ID') } = $node->textContent; } return %pairs; }

    FWIW, traditionally this is done using .po/.mo files, each language gets its own file ... gettext.. and all that ... :)

Re: language selection via libxml
by Jenda (Abbot) on Jan 20, 2014 at 17:05 UTC

    Are you sure you want to parse and reparse the XML many times for each individual widget? I'd rather parse it just once at the beginning or at most once when the language is changed.

    use XML::Rules; my $parser = XML::Rules->new(rules=>{ widget => 'content by ID', language => 'pass no content', _default => 'no content' }); my $data = $parser->parse(\*DATA); use Data::Dumper; print Dumper($data); # $data{english}{1} == "input" __DATA__ <?xml version="1.0"?> <language> <english> <widget ID="1">input</widget> <widget ID="2">output</widget> </english> <deutsch> <widget ID="1">eingabe</widget> <widget ID="2">ausgabe</widget> </deutsch> </language>

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1071286]
Approved by hdb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (7)
As of 2024-04-18 12:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found