2016-12-02 46 views
1

如何用perl

我有我的projects.xml文件,如下基於另一個節點的價值得到XML節點值:

<projects> 
    <project> 
     <id>ID_ABCD1</id> 
     <name>ptest1</name> 
    </project> 
    <project> 
     <id>IDB_abcd</id> 
     <name>ptest1</name> 
     <branch>bnm1</branch> 
     <branched_from_id>ID_ABCD1</branched_from_id> 
     <branched_from_version>111</branched_from_version> 
    </project> 
    <project> 
     <id>ID_ABCD2</id> 
     <name>ptest2</name> 
    </project> 
    <project> 
     <id>IDB_abcd2</id> 
     <name>ptest2</name> 
     <branch>bnm2</branch> 
     <branched_from_id>ID_ABCD2</branched_from_id> 
     <branched_from_version>111</branched_from_version> 
    </project> 
</projects> 

在我現有的代碼,我根據項目的ID獲取項目名稱從另一個文件categories.xml獲得。

對於這些項目的名字我要搜索的是有它的任何branch元素,如果該元素存在,那麼我得 相應branch名稱和branched_from_version

branched_from_id value是其他項目的ID。

#!/usr/bin/env perl 

use strict; 

use XML::LibXML; 
use File::Basename; 
use File::Find::Rule; 
use XML::Twig; 

my $cat_xml = '/home/Ras/categories.xml'; 
my $twig  = XML::Twig->parse($cat_xml); 
my $doc  = XML::LibXML->new->parse_file($cat_xml); 

my $proj_xml = '/home/Ras/projects.xml'; 
my $twigp = XML::LibXML->new->parse_file($proj_xml); 

my @nodes = $doc->findnodes('/categories/category'); 

my $catname = "/home/Ras/category.txt"; 

open FH, "> $catname" or warn "not able to open catname file"; 

foreach my $catnode (@nodes) { 
    my @catn = $catnode->findvalue('@name'); 
    print FH "@catn \n"; 
} 

my @catlist = `cat /home/Ras/category.txt`; 

foreach my $cat (@catlist) { 

    chomp($cat); 
    $cat =~ s/^\s+|\s$//g; 

    my $path = "./category[\@name=\"$cat\"]/project"; 

    foreach my $project ($twig->findnodes("$path")) { 

     my $projout = $project->text; 

     foreach my $projname ($twigp->findvalue("/projects/project[id = '$projout']/name")) { 

     } 
    } 
} 

在上面的代碼中包含$projoutproject.xml文件的ID值。但那些與branch節點的ID值不存在。

我有$projname名稱值。因此,根據$projname中的名稱值,我需要獲取相應的branch值和branched_from_version值。

+1

你爲什麼要混合使用XML :: Twig和XML :: LibXML?這看起來像通往痛苦的道路。 – Sobrique

+0

你能澄清一下預期的投入和產出嗎?也許我們可以運行一個[mcve],以及期望的輸出是什麼? – Sobrique

+0

這有點混亂。您從'categories.xml'創建'category'名稱列表並將其寫入磁盤;然後你將它讀回來,並搜索相同的XML文件來查找那些'category'元素!如果你需要幫助,你還需要顯示'categories.xml'。 – Borodin

回答

1

這是一個有點簡單,但我認爲你正在試圖做這樣的事情:

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

use XML::Twig; 

my $twig = XML::Twig -> parsefile ('test.xml'); 
my $project = 'ptest2'; 

if ($twig -> get_xpath("//project/name[string()=\"$project\"]")) { 
    print $twig -> get_xpath("//project/name[string()=\"$project\"]",0) -> text, " exists\n"; 
    foreach my $branch ($twig -> get_xpath("//project/name[string()=\"$project\"]/../branched_from_id/..",0)) { 
     print "$project : ", $branch -> first_child_text('branched_from_id'), " => ", $branch -> first_child_text('branched_from_version'),"\n"; 
    } 
} 

我已經砍了,因爲我沒有自己的項目列表。但是,這將使用XML::Twigget_xpath找到一個項目名稱 - 雖然注意,它不區分是否它是一個分支或第一部分的檢查。

然後根據「匹配」的所有分支的匹配情況抽出匹配xpath