1

Perl ハッシュに問題があります。私はXMLを持っています:

<?xml version="1.0" encoding="utf-8"?>
<SvnRequestUsers>
  <AccessCode>$TR0ngP@ssvv0rd!</AccessCode>
  <SvnUsers>
    <SvnUser>
      <Username>svn.testname</Username>
      <Password>jA=B*+q%</Password>
      <Create>true</Create>
    </SvnUser>
    <SvnUser>
      <Username>svn.testname2</Username>
      <Password>jA=B*+q%</Password>
      <Create>true</Create>
    </SvnUser>
  </SvnUsers>
</SvnRequestUsers>

SvnUser ノードをループしたい。私が使うとき

私の $usersList = $ref->{'SvnUsers'};

foreach my $key ( @{$usersList->{'SvnUser'}} )
{ ..... }

これは、複数のノードがある場合に機能しますが、1 つのノードでは機能しません。

使用時

私の @usersList = $ref->{'SvnUsers'}->{'SvnUser'};

foreach my $key ( @usersList )
{ ..... }

これは、ノードが 1 つだけ存在する場合にのみ機能します。トリックはどこにありますか???

4

5 に答える 5

2

XML::Simple を使用している場合は、ForceArray をグローバルに (おそらくコードに配列の逆参照を追加する必要があります)、または 1 つまたは複数のノードを持つ特定の要素に対してオンにする必要があります。https://metacpan.org/module/XML::Simple#ForceArray-names-in---importantを参照してください。

于 2013-01-31T22:23:34.617 に答える
1

これは単純とはかけ離れたXML::Simple. 名前空間を最初に主張したことで人気を博したと確信していますが、IMO には多くの欠点があります。

私の推測が正しければ、オプションを有効にすることで、いくつかのぎこちなさを克服できForceArrayます。モジュールのPODは言う

ほぼ確実にオンにしたいので、ForceArrayをチェックしてください

あなたの場合、XML のその時点で要素が1 つしかない場合でも、これ$ref->{SvnUsers}{SvnUser}常に配列参照であることを確認します。<SvnUser>その$ref->{SvnUsers}{SvnUser}[0]ため、一貫して最初または唯一のユーザー要素にアクセスします。

私のアドバイスは、より一貫性のある XML モジュールにアップグレードすることです。XML::Smart構造体と非常によく似た方法でデータにアクセスできますが、より優れた DWIM インターフェイスを提供するためXML::Simpleに を広範囲に使用します。tieたとえば、最初の要素XML::Smartの最初の下には、またはを使用してアクセスできます。SvnUserSvnUsers$ref->{SvnUsers}{SvnUser}$ref->{SvnUsers}[0]{SvnUser}[0]

に切り替えるだけでXML::Smart、当面の問題は解決します。たとえば、以下のコードは、すべてのユーザーのユーザー名を一覧表示します。ユーザーが 1 人であろうと複数であろうと (または実際には何もありません。その場合、オブジェクトは空のリストを返します)。

XML::LibXML私自身の好みは、または のような「適切な」XMLモジュールですXML::Twigが、もちろん選択はあなた次第です。

use strict;
use warnings;

use XML::Smart;

my $ref = XML::Smart->new(\*DATA);

my $users_list= $ref->{SvnRequestUsers}{SvnUsers};

foreach my $key ( @{ $users_list->{SvnUser} } ) {
  print $key->{Username}, "\n";
}

__DATA__
<?xml version="1.0" encoding="utf-8"?>
<SvnRequestUsers>
  <AccessCode>$TR0ngP@ssvv0rd!</AccessCode>
  <SvnUsers>
    <SvnUser>
      <Username>svn.testname</Username>
      <Password>jA=B*+q%</Password>
      <Create>true</Create>
    </SvnUser>
    <SvnUser>
      <Username>svn.testname2</Username>
      <Password>jA=B*+q%</Password>
      <Create>true</Create>
    </SvnUser>
  </SvnUsers>
</SvnRequestUsers>

出力

svn.testname
svn.testname2
于 2013-01-31T22:55:07.530 に答える
0

いつものように、 Mojoliciousスイートの一部であるMojo::DOMをお勧めします。セレクターと変換/イテレーターメソッドを使用すると、問題は非常に単純になります。

#!/usr/bin/env perl

use strict;
use warnings;

use Mojo::DOM;

my $dom = Mojo::DOM->new(<<'END');
<?xml version="1.0" encoding="utf-8"?>
<SvnRequestUsers>
  <AccessCode>$TR0ngP@ssvv0rd!</AccessCode>
  <SvnUsers>
    <SvnUser>
      <Username>svn.testname</Username>
      <Password>jA=B*+q%</Password>
      <Create>true</Create>
    </SvnUser>
    <SvnUser>
      <Username>svn.testname2</Username>
      <Password>jA=B*+q%</Password>
      <Create>true</Create>
    </SvnUser>
  </SvnUsers>
</SvnRequestUsers>
END

# get an array

my @users = $dom->find('SvnUser')
                ->pluck('Username')
                ->pluck('text')
                ->each;

# or do something with each element

$dom->find('SvnUser')
    ->pluck('Username')
    ->pluck('text')
    ->each(sub{ print "$_\n" });

もちろん、実際にユーザー名が必要な場合は、より調整されたセレクターfind('SvnUser Username')を使用することもできます。上記の例は、メソッドを示すことです。

于 2013-02-01T04:53:13.523 に答える
0

これをやってみてください:

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

use XML::XPath;
use XML::XPath::XMLParser;

my $xp = XML::XPath->new(filename => 'file.xml');

my $nodeset = $xp->find('/SvnRequestUsers/SvnUsers/SvnUser'); # find svn users

foreach my $node ($nodeset->get_nodelist) {
    print "FOUND\n\n",
        XML::XPath::XMLParser::as_string($node),
        "\n\n";
}

結果 :

FOUND

<SvnUser>
      <Username>svn.testname</Username>
      <Password>jA=B*+q%</Password>
      <Create>true</Create>
    </SvnUser>

FOUND

<SvnUser>
      <Username>svn.testname2</Username>
      <Password>jA=B*+q%</Password>
      <Create>true</Create>
    </SvnUser>
于 2013-01-31T22:03:01.227 に答える
0

Ahref で XML を読み取るためにどのモジュールを使用しますか? さらに多くのユーザーがいる場合は、次のようにデータにアクセスする必要があると思います。

my @usersList = $ref->{'SvnUsers'}->[0]->{'SvnUser'};

「SvnUsers」キーの下に値として配列参照があるため、これにより最初のユーザーが得られます。

反復は次のようになります。

my $maxusers = scalar(@{$ref->{'SvnUsers'}}); # get the number of elements in your ref
for my $i(0 .. $maxusers){
    my $svnuser = $ref->{'SvnUsers'}->[$i]->{'SvnUser'}; # get current
    ....... # do your stuff
}
于 2013-01-31T21:58:10.407 に答える