2017-05-24 18 views
2

私はXML :: LibXMLを使用していくつかの問題を抱えています。私は何をしたいのか、またはXMLを変更する必要があるかどうかを知りたいと思います。下では異なるもので、あなたが見ることができるよう、「アクション」の下で、アクション(1または各種類の複数のアクションの異なるタイプがあることができPerl XML :: LibXML usage

<fftg> 
    <actions> 

      <rename> 
        <mandatory>0</mandatory> 
        <other_things_here /> 
      </rename> 

      <transfer> 
        <mandatory>0</mandatory> 
        <protocol>SFTP</protocol> 
        <other_things_here /> 
      </transfer> 

      <transfer> 
        <mandatory>1</mandatory> 
        <protocol>FTP</protocol> 
        <other_things_here /> 
      </transfer> 

      <archive> 
        <mandatory>1</mandatory> 
        <other_things_here /> 
      </archive> 

      <rename> 
        <mandatory>1</mandatory> 
        <other_things_here /> 
      </rename> 

    </actions> 

</fftg> 

:現時点で

、私のXMLは次のようになりますそれぞれのアクション)

アクションに応じて、それぞれのアクションをブラウズして特定のものを実行したいと思います。

私の問題は、同じ種類の複数のアクションがあるため、スクリプトが正しく動作しておらず、同じ種類の以前のアクションを上書きするか、同じアクションのループで特定のアクションのループが再ループします。種類

例1:

foreach my $transfer ($doc->findnodes('/fftg')) { 

    # Browse Actions 
    foreach my $action ($doc->findnodes('/fftg/actions/*')) { 

      my $action_name = $action->nodeName(); 
      my $actiontype = ucfirst($action->nodeName()); 
      print "executing action $action_name ..\n"; 

      # Browse action details 
      foreach my $action_details ($doc->findnodes('/fftg/actions/'.$action_name)) { 
        for my $detail ($action_details->findnodes('./*')) { 
          print $detail->nodeName(), ": ", $detail->textContent(), "\n"; 
        } 
      } 
      print "-------------\n"; 
    } 
} 

結果1:

executing action rename .. 
mandatory: 0 
other_things_here: 
mandatory: 1 
other_things_here: 
------------- 
executing action transfer .. 
mandatory: 0 
protocol: SFTP 
other_things_here: 
mandatory: 1 
protocol: FTP 
other_things_here: 
------------- 
executing action transfer .. 
mandatory: 0 
protocol: SFTP 
other_things_here: 
mandatory: 1 
protocol: FTP 
other_things_here: 
------------- 
executing action archive .. 
mandatory: 1 
other_things_here: 
------------- 
executing action rename .. 
mandatory: 0 
other_things_here: 
mandatory: 1 
other_things_here: 
------------- 

あなたが見ることができるように、この結果は良いですが、ド(各 "アクションタイプ" のように、間違っていますそれは、同じ種類のすべてのアクションでループしています。

これが原因にある:私は私が達成したいものを作るために何ができるか

foreach my $action_details ($doc->findnodes('/fftg/actions/'.$action_name)) { 

?私が欲しいもの(XMLを変更せずに可能ならば)

は次のとおりです。

executing action rename .. 
mandatory: 0 
other_things_here: 
------------- 
executing action transfer .. 
mandatory: 0 
protocol: SFTP 
other_things_here: 
------------- 
executing action transfer .. 
mandatory: 1 
protocol: FTP 
other_things_here: 
------------- 
executing action archive .. 
mandatory: 1 
other_things_here: 
------------- 
executing action rename .. 
mandatory: 1 
other_things_here: 
------------- 

はサイドノートであなた

に感謝し、私は私のXMLを変更し、修正する代わりにそのようなものを使用することができたとしXSDは後で生産するのが難しいため、以下の2つを避けたいと思います(それぞれのアクションタイプに固有のオプションが必要です):

<fftg> 
<actions> 
     <action> 
       <type>rename</type> 
       <mandatory>0</mandatory> 
       <other_things_here /> 
     </action> 

     <action> 
       <type>transfer</type> 
       <mandatory>0</mandatory> 
       <protocol>SFTP</protocol> 
       <other_things_here /> 
     <action> 

     <action> 
       <type>transfer</type> 
       <mandatory>0</mandatory> 
       <protocol>FTP</protocol> 
       <other_things_here /> 
     <action> 

     <action> 
       <type>archive</type> 
       <mandatory>0</mandatory> 
       <other_things_here /> 
     <action> 

     <action> 
       <type>rename</type> 
       <mandatory>0</mandatory> 
       <other_things_here /> 
     <action> 



</actions> 

</fftg> 

または

<fftg> 
<actions> 
     <action type="rename"> 
       <mandatory>0</mandatory> 
       <other_things_here /> 
     </action> 

     <action type="transfer"> 
       <mandatory>0</mandatory> 
       <protocol>SFTP</protocol> 
       <other_things_here /> 
     <action> 

     <action type="transfer"> 
       <mandatory>0</mandatory> 
       <protocol>FTP</protocol> 
       <other_things_here /> 
     <action> 

     <action type="archive"> 
       <mandatory>0</mandatory> 
       <other_things_here /> 
     <action> 

     <action type="rename"> 
       <mandatory>0</mandatory> 
       <other_things_here /> 
     <action> 



</actions> 

</fftg> 

おかげで再び に関して、

+0

...他の質問にあなたが属性を持っていた '' 内の要素を持っていた:二つのループは(<action/>子供の一つであり、子供たちに別のものを)動作するはずです。物事を変えるかもしれないのでここでも言及する価値があります。 – simbabque

答えて

4

まず、あなたのXPath式は、ドキュメントのルートノードに対して評価されることを意味し、$docfindnodesを呼び出します。第2に、使用するXPath式は '/'で始まります。つまり、トップレベルのノードにルートされます。

$doc->findnodes('/fftg/actions/rename') 

それは「私の文書のルート・ノードである<fftg/>要素の子である<actions/>要素の子であるすべての<rename/>要素を与える」、および、結果として、あなたが得る意味:あなたが呼ぶとき、だから文書内にあるノードはすべて<rename/>です。

さらに、ループが多すぎます。最初の1つは冗長です。ルート要素が1つしかないからです。このすべてを読む前に

for my $action ($doc->findnodes('/fftg/actions/*')) { 
    print "executing ", $action->nodeName(), "\n"; 
    for my $detail ($action->findnodes('./*')) { 
     print $detail->nodeName(), ": ", $detail->textContent(), "\n"; 
    } 
} 
関連する問題