2014-11-24 45 views
1

我從一個服務下面的DiffGram XML:我該如何用perl解析diffgam.xml文件以獲取散列數組而不是大散列圖?

<?xml version="1.0"?> 
<xvcs:diffgram xmlns:xvcs="http://www.xvcs.org/"> 
    <xvcs:update id="7" first-child-of="/opt/node/node[1]"> 
    <xvcs:attr-update name="location" old-value="???" new-value="testlocation"/> 
    </xvcs:update> 
    <xvcs:update id="35" follows="/opt/node/node[2]"> 
    <xvcs:attr-update name="URL" old-value="/" new-value="/testurl/"/> 
    </xvcs:update> 
    <xvcs:insert id="75" first-child-of="/opt"> 
    <node node_id="/1234" location="new location" URL="/newurl"></node> 
    </xvcs:insert> 
</xvcs:diffgram> 

我與XML ::這樣簡單解析它:

my $diffgram_hashref = XMLin($diffgram->toString(1), 
           KeepRoot => 1, 
           ForceArray => 1, 
         ); 

$logger->debug(dump($diffgram_hashref)); 

,並得到以下結果:

{ 
    "xvcs:diffgram" => [ 
    { 
     "xmlns:xvcs" => "http://www.xvcs.org/", 
     "xvcs:insert" => { 
         75 => { 
           "first-child-of" => "/opt", 
           "node" => [ 
            { 
            node_id => "/1234", 
            location => "new location", 
            URL  => "/newurl", 
            }, 
           ], 
           }, 
         }, 
     "xvcs:update" => { 
         7 => { 
           "first-child-of" => "/opt/node/node[1]", 
           "xvcs:attr-update" => { 
                 location => { "new-value" => "testlocation", "old-value" => "???" }, 
                 }, 
           }, 
         35 => { 
           "follows" => "/opt/node/node[2]", 
           "xvcs:attr-update" => { 
             URL => { "new-value" => "/testurl/", "old-value" => "/" }, 
           }, 
           }, 
         }, 
    }, 
    ], 
} 

我嘗試了幾個ForeArray/KeyAttr組合,但我沒有實現將diffgram語句(更新,插入)作爲數組以便按正確的順序繼續它們:

{ 
    "xvcs:diffgram" => [ 
    { 
     "xvcs:update" => { 
         7 => { 
           "first-child-of" => "/opt/node/node[1]", 
           "xvcs:attr-update" => { 
                 location => { "new-value" => "testlocation", "old-value" => "???" }, 
                 }, 
           } 
         } 
    }, 
    { 
     "xvcs:update" => { 
         35 => { 
           "follows" => "/opt/node/node[2]", 
           "xvcs:attr-update" => { 
             URL => { "new-value" => "/testurl/", "old-value" => "/" }, 
           }, 
           }, 
         } 
    }, 
    { 
     "xvcs:insert" => { 
         75 => { 
           "first-child-of" => "/opt", 
           "node" => [ 
            { 
            node_id => "/1234", 
            location => "new location", 
            URL  => "/newurl", 
            }, 
           ], 
           }, 
         }, 
    } 
    ] 
} 

請問有人能幫我嗎?

+0

當你說你嘗試了幾種組合......究竟是什麼你嘗試和你有什麼要完成?我會建議你想要的是非常簡單的使用XML:Twig而不是XML :: Simple是前進的方向。 – Sobrique 2014-11-24 15:46:50

+0

我嘗試了不同組合的ForceArray和KeyAttr,比如'my $ diffgram_hashref = XMLin($ diffgram-> toString(1),KeepRoot => 1,ForceArray => ['xvcs:insert','xvcs:update'],KeyAttr = >爲undef);' 或 '我的$ diffgram_hashref = XMLin($ diffgram->的toString(1),KeepRoot => 1,ForceArray => [ 'xvcs:的DiffGram'],KeyAttr =>爲undef);' 我會看看XML :: Twig,thx的那個提示 – user3337084 2014-11-24 15:54:13

+0

你究竟在努力完成什麼?腳本的預期輸出是什麼?你想按順序處理每個元素嗎? – Sobrique 2014-11-24 16:35:40

回答

1

該程序通過使用XML::Twig模塊來完成。我忽略了頂級散列鍵xvcs:diffgram,因爲該散列只有一個元素。這同樣適用於數組中的每個散列 - 我寧願將元素標記看作是子散列的其中一個元素的值,因爲就其本身而言,您有一組元素散列;但是我已經在描述它時留下了這個結構。

我也離開了idnameURL屬性作爲簡單的哈希元素,而不是專門爲你的榜樣做處理它們。我使用Data::Dump只顯示從數據構建的結構。

use strict; 
use warnings; 

use XML::Twig; 

my $twig = XML::Twig->new; 
$twig->parse(\*DATA); 

my @data; 

for my $node ($twig->root->children) { 

    my $atts = $node->atts; 

    for my $child ($node->children) { 
    $atts->{$child->tag} = $child->atts; 
    } 

    push @data, { $node->tag => $atts }; 
} 

use Data::Dump; 
dd \@data; 



__DATA__ 
<?xml version="1.0"?> 
<xvcs:diffgram xmlns:xvcs="http://www.xvcs.org/"> 
    <xvcs:update id="7" first-child-of="/opt/node/node[1]"> 
    <xvcs:attr-update name="location" old-value="???" new-value="testlocation"/> 
    </xvcs:update> 
    <xvcs:update id="35" follows="/opt/node/node[2]"> 
    <xvcs:attr-update name="URL" old-value="/" new-value="/testurl/"/> 
    </xvcs:update> 
    <xvcs:insert id="75" first-child-of="/opt"> 
    <node node_id="/1234" location="new location" URL="/newurl"></node> 
    </xvcs:insert> 
</xvcs:diffgram> 

輸出

[ 
    { 
    "xvcs:update" => { 
     "first-child-of" => "/opt/node/node[1]", 
     "id" => 7, 
     "xvcs:attr-update" => { 
     "name" => "location", 
     "new-value" => "testlocation", 
     "old-value" => "???", 
     }, 
    }, 
    }, 
    { 
    "xvcs:update" => { 
     "follows" => "/opt/node/node[2]", 
     "id" => 35, 
     "xvcs:attr-update" => { 
     "name" => "URL", 
     "new-value" => "/testurl/", 
     "old-value" => "/", 
     }, 
    }, 
    }, 
    { 
    "xvcs:insert" => { 
     "first-child-of" => "/opt", 
     "id" => 75, 
     "node" => { 
     location => "new location", 
     node_id => "/1234", 
     URL => "/newurl", 
     }, 
    }, 
    }, 
] 
1

根據迄今爲止的評論,這是一個不完整的解決方案。希望它能說明爲什麼鮑羅廷和我正在請求你真正的試圖擺脫你的解析。

use strict; 
use warnings; 

use XML::Twig; 

my $twig = XML::Twig->new()->parse(\*DATA); 

foreach my $thing ($twig->root->children()) { 
    print $thing ->tag, "\n"; 
    foreach my $att (keys %{ $thing->atts() }) { 
     print "\t", $att, "=", $thing->att($att), "\n"; 
    } 
    my $op = $thing->first_child; 
    print "\t\t", $op->name, "\n"; 
    foreach my $att (keys %{ $op->atts }) { 
     print "\t\t\t", $att, "=", $op->att($att), "\n"; 
    } 

} 

__DATA__ 
<?xml version="1.0"?> 
<xvcs:diffgram xmlns:xvcs="http://www.xvcs.org/"> 
    <xvcs:update id="7" first-child-of="/opt/node/node[1]"> 
    <xvcs:attr-update name="location" old-value="???" new-value="testlocation"/> 
    </xvcs:update> 
    <xvcs:update id="35" follows="/opt/node/node[2]"> 
    <xvcs:attr-update name="URL" old-value="/" new-value="/testurl/"/> 
    </xvcs:update> 
    <xvcs:insert id="75" first-child-of="/opt"> 
    <node node_id="/1234" location="new location" URL="/newurl"></node> 
    </xvcs:insert> 
</xvcs:diffgram> 

這將打印:

xvcs:update 
    first-child-of=/opt/node/node[1] 
    id=7 
     xvcs:attr-update 
      old-value=??? 
      new-value=testlocation 
      name=location 
xvcs:update 
    follows=/opt/node/node[2] 
    id=35 
     xvcs:attr-update 
      old-value=/ 
      new-value=/testurl/ 
      name=URL 
xvcs:insert 
    first-child-of=/opt 
    id=75 
     node 
      URL=/newurl 
      location=new location 
      node_id=/1234 

他們關鍵點在於將你的XML轉換散列的數組是 - 可能 - 一個XY problem。你專注於嘗試以某種方式做事,而答案是 - 可能 - 不這樣做。

+0

我不知道「XY問題」是這樣調用的。感謝您的鏈接和您的幫助 – user3337084 2014-11-24 17:25:49

相關問題