(這是JSON化嵌套的Perl物件的XML變體)
在創建我的物件的 XML 演示時,我推遲了為子物件創建 XML 的時間。 在最初的版本可以使用,但創建了一個不必要的深度嵌套結構后,我試圖在一定程度上平坦該結構,但遇到了一個問題,我只能通過一些丑陋的變通方法來解決。
讓我們來看看這個代碼片段(在一個foreach回圈中執行):
my $child = XML::Twig::Elt->new('s sample', { 'name' => $_ }) 。
my $F = $val->{$_}-> XML_string($child);
$F->print;
$child = $elt->insert_new_elt(last_child => 'dummy'/span>)。
$child->replace_with($F)。
$F(為除錯目的分配到一個臨時變數)包含物件的XML子樹$val->{$_}。
($val是當前正在處理的物件槽,在這種情況下,它是一個子物件的集合(哈希)。
所以$val->{$_}是要處理的子物件)。)
子樹被添加為額外引數($child,即:sample)的子女。
我想做的是$elt->insert_new_elt(last_child => $F);,但這永遠不會成功。
所以我在正確的位置插入了一個dummy元素,只是為了事后替換它。
下面是這些行的一些除錯輸出:
### The parent node where the new 'sample' children should be added
DB<4> p $elt->print。
<perf_data/>。
### The new child (it's still too complex...)
DB<5> p $F->print。
<樣本名稱="max"><標簽>max</label><值>2。 48584</value><unit/><warn><range part="end"/span>>0. 5</range><range part="倒置">0</range><range part="start">0< /range></warn><crit>< range part="end">1< /range><range part="inverted">0</range><range part="start"/span>>0< /range></crit><min>0<min><max/><;/sample>。
### ###假的孩子
DB<6> p $child->print
<dummy/>。
### 添加假孩子后的父本。
DB<7> p $elt->print。
<perf_data><dummy/></perf_data>
### 在用真正的孩子替換了假的孩子之后,##父孩子
DB<8> p $elt->print
<perf_data><樣本名稱="max"><標簽>max</label><值>2. 48584</value><unit/><warn><range part="end"/span>>0. 5</range><range part="倒置">0</range><range part="start">0< /range></warn><crit>< range part="end">1< /range><range part="inverted">0</range><range part="start"/span>>0</range> </crit><min>0</min><max/></sample></perf_data>
### 更多的 "樣本 "元素在后面......。
我怎樣才能避免臨時的dummy元素?
我試圖從檔案中找到pout,但沒有成功。
也許為了按順序添加子元素,我應該使用insert_new_elt以外的東西(也許是append_new_elt?),但是大部分的檔案是關于決議現有的XML,而不是構建XML。
簡化的替代版本
由于有人要求我提供一個簡化的版本,所以這里有一個。 然而它與原始資料結構只有一點點相似。 至少我試圖保留問題的本質。所以這里是代碼。
所以這里是代碼:
#!/usr/bin/perl
use strict;
使用警告。
use 5.018;
package FOO;
use constant ATTRIBUTES => (
['a', 0] 。
['b', 1]。
['c', 2]。
['d', 3]。
);
sub new($)
{
my $class = shift;
my $self = [];
$#$self = 4;
bless $self, $class;
foreach (@$self) {
$_ = int(rand(10)
}
return $self;
}
使用 XML::Twig。
sub XML_string($;$)
{
my ($self, $root) = @_;
$root //= XML::Twig::Elt->new(__PACKAGE__)。
foreach (ATTRIBUTES) {
my ($name, $i) = @$_[0, 1] 。
if (defined(my $val = $self-> [$i])) {
my $elt = $root->insert_new_elt(last_child => $name) 。
if ($i == 1 || $i == 2) {
my $range = $elt->insert_new_elt(last_child => 'range'/span>)。
$range->set_att('baz' => $val)。
}
} # else leave out[/span]。
}
return $root;
}
package BAR;
使用常量ATTRIBUTES => (
['e', 0] 。
['f', 1]。
['g', 2] 。
['h', 3]。
);
sub new($)
{
my $class = shift;
my $self = [];
$#$self = 4;
bless $self, $class;
foreach (@$self) {
$_ = int(rand(10)
}
return $self;
}
使用 XML::Twig。
sub XML_string($;$)
{
my $self = shift;
my $xml = XML::Twig->new()->set_xml_version('1.0'/span>)->set_encoding('utf-8'/span>) 。
my $b = XML::Twig::Elt->new(__PACKAGE__, {'version' => '1.0'}) 。
$xml->set_root($b)。
foreach (ATTRIBUTES) {
my ($name, $i) = @$_[0, 1] 。
if (defined(my $val = $self-> [$i])) {
my $elt = $b->insert_new_elt(last_child => $name) 。
if ($i == 1) {
my $e = $elt->insert_new_elt(last_child => 's sample') 。
my $F = $val->XML_string($e);
#print $F->print,"
";;
$e = $el->insert_new_elt(last_child => 'dummy'/span>)。
$e->replace_with($F)。
}
} # else leave out。
}
if ($#_ >= 0 && $_[0] ) {
$xml->set_pretty_print('indented') 。
}
return $xml-> sprint();
}
package main;
my $f1 = FOO->new();
my $f2 = FOO->new();
my $b = BAR->new();
$b->[1] = $f1;
$b->[2] = $f2;
print $b->XML_string(1), "
"。
而一個樣本輸出可能看起來像這樣:
DB<3> x $b
0 BAR=ARRAY(0x1b83860)
0 1
1 FOO=ARRAY(0xe2ad40)
02
1 4 4
2 0
3 4
4 7 7
2 FOO=ARRAY(0x1633788)
0 3
1 8 8
2 0
3 1
4 0
3 3
4 1
DB<4> n
<?xml version="1.0" encoding="utf-8"? >
<BAR version="1.0">
<e/>
<f>
<樣本>
<a/>
<b>
<range baz="4"/span>/>
</b>
<c>
<range baz="0"/>
</c>
<d/>
</sample>
</f>
<g/>
<h/>
</BAR>
我希望它與原來的問題足夠相似。
uj5u.com熱心網友回復:
不要為新元素使用建構式。直接使用insert_new_elt的建構式引數:
my $child = $elt-> insert_new_elt(last_child => 's sample', {name => $_}) 。
$val->{$_}->XML_string($child)。
或者,使用paste:
my $child = XML::Twig::Elt->new('s sample', {name => $_}) ;
$child->粘貼(last_child => $elt)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/311343.html
標籤:
