Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re: What is correct way to reference?

by haukex (Bishop)
on May 22, 2017 at 17:51 UTC ( #1190869=note: print w/replies, xml ) Need Help??

in reply to What is correct way to reference?

One element could either have a single value or an array of values.

I agree with Your Mother, sounds like you might be using XML::Simple. I have to strongly recommend against this module (as its own documentation does, see the section "Status of this Module"), except for maybe the very simplest of cases, of which this is probably not one. Instead, look into other XML parsing modules, such as XML::LibXML, XML::Twig, or XML::Rules, which can output data structures much like XML::Simple:

use warnings; use strict; use Data::Dump; use XML::Rules (); my $XML1 = '<root><phone><callTo>X</callTo></phone></root>'; my $XML2 = '<root><phone><callTo>Y</callTo> <callTo>Z</callTo></phone></root>'; my $parser = XML::Rules->new( stripspaces => 3|4, rules => [ root => 'pass', phone => 'as is', callTo => 'content array', _default => sub { die "Unknown tag $_[0]" }, ] ); dd $parser->parse($XML1); dd $parser->parse($XML2); __END__ { phone => { callTo => ["X"] } } { phone => { callTo => ["Y", "Z"] } }

As for XML::Simple, note its ForceArray option:

use XML::Simple qw/:strict XMLin/; dd XMLin($XML1, KeyAttr=>{}, ForceArray=>[]); dd XMLin($XML2, KeyAttr=>{}, ForceArray=>[]); dd XMLin($XML1, KeyAttr=>{}, ForceArray=>['callTo']); __END__ { phone => { callTo => "X" } } { phone => { callTo => ["Y", "Z"] } } { phone => { callTo => ["X"] } }

Lastly, to answer your original question, if you have a scalar that holds either a single value or an array reference, one way to handle that is like the following. However, it should be clear from the above that this is not the best way to fix your problem.

foo( "one" ); foo( ["two", "three"] ); sub foo { my $x = shift; # the following does the trick my @values = ref $x eq 'ARRAY' ? @{$x} : $x; for my $val (@values) { print "<$val>\n"; } } __END__ <one> <two> <three>

Update: Refactored last code example slightly to make the solution more clear. Update 2: Used callTo => 'content array' instead of 'as array' to make XML::Rules output identical to XML::Simple.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1190869]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2021-08-03 16:30 GMT
Find Nodes?
    Voting Booth?
    My primary motivation for participating at PerlMonks is: (Choices in context)

    Results (39 votes). Check out past polls.