我正在尝试将值写入XML文件。我有一个CSV输入文件Input.xsv
和一个XML模板文件template.xml
,我需要使用CSV文件中的名称和IP地址值进行更新。
LAB-1,10.26.0.1
LAB-2,10.26.0.2
LAB-3,10.26.0.3
<?xml version="1.0" encoding="UTF-8"?>
<ns0:networkdevice
xmlns:ns0="network.ers.ise.cisco.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns1="ers.ise.cisco.com"
xmlns:ers="ers.ise.cisco.com"
name="name1">
<authenticationSettings>
<enableKeyWrap>true</enableKeyWrap>
<keyEncryptionKey>1234567890123456</keyEncryptionKey>
<keyInputFormat>ASCII</keyInputFormat>
<networkProtocol>RADIUS</networkProtocol>
<radiusSharedSecret>aaa</radiusSharedSecret>
</authenticationSettings>
<coaPort>1700</coaPort>
<NetworkDeviceIPList>
<NetworkDeviceIP>
<ipaddress>1.1.1.1</ipaddress>
<mask>32</mask>
</NetworkDeviceIP>
</NetworkDeviceIPList>
</ns0:networkdevice>
我想从CSV文件中读取名称和IP地址,并将它们写入我的XML模板文件,以便为CSV文件中的每个设备创建HTTP POST请求。
我尝试将值保存在我的XML模板中,但我不确定我是否正确。
#!/usr/bin/perl
use warnings;
use strict;
use Text::CSV;
use XML::TreeBuilder;
use Data::Dumper;
my $xmlbase = 'template.xml';
my $paramsfile = 'input.csv';
# The list of tags filled from the CSV file
my @taglist = qw( name ipaddress );
my $tree = XML::TreeBuilder->new();
$tree->parsefile($xmlbase);
my $csv = Text::CSV->new();
open my $fh, "<:encoding(utf8)", $paramsfile or die "$paramsfile: $!";
while ( my $row = $csv->getline($fh) ) {
my $contree = XML::TreeBuilder->new();
$contree->parsefile($xmlbase);
my $index = 0;
for my $tagname ( @taglist ) {
my $tag = $contree->look_down('_tag' => $tagname);
$tag->push_content($row->[$index++]);
}
}
print '<?xml version="1.0" encoding="UTF-8"?>'."\n";
print $tree->as_XML();
运行脚本后,我收到此错误:
无法在此行中找到对象方法“push_content”
此错误引用语句$tag->push_content($row->[$index++]);
。我认为这是因为name
没有自己的标签。
我在这里有这个元素:
<ns0:networkdevice
xmlns:ns0="network.ers.ise.cisco.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns1="ers.ise.cisco.com"
xmlns:ers="ers.ise.cisco.com"
name="name1">
标记ns0:networkdevice
中的
当我尝试使用ipaddress
时,会打印出来,但是来自template.xml
的原始值。它不会从Input.csv
获取值,如果它为空,则它保持为空。
我该怎么做?
答案 0 :(得分:1)
从Perl生成XML的简单方法是使用XML::FromPerl。
模板由代码中嵌入的Perl数据结构取代:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use XML::FromPerl qw(xml_from_perl);
my $name = 'LAB-1';
my $ip = '10.26.0.1';
my $xml = xml_from_perl
[ 'ns0:networkdevice' => { 'xmlns:ns0' => 'network.ers.ise.cisco.com',
'xmlns:xs' => 'http://www.w3.org/2001/XMLSchema',
'xmlns:ns1' => 'ers.ise.cisco.com',
'xmlns:ers' => 'ers.ise.cisco.com',
name => $name },
[ authenticationSettings =>
[ enableKeyWrap => 'true' ],
[ keyEncryptionKey => '1234567890123456' ],
[ keyInputFormat => 'ASCII' ],
[ networkProtocol => 'RADIUS' ],
[ radiusSharedSecret => 'aaa' ] ],
[ coaPort => '1700' ],
[ NetworkDeviceIPList =>
[ NetworkDeviceIP =>
[ ipaddress => $ip ],
[ mask => 32 ] ] ] ];
say $xml->toString(1);
答案 1 :(得分:0)
我对XML::Treebuilder
不熟悉,所以会在XML::Twig
中给出一个例子。我也会避免使用Text::CSV
,因为我认为对于大多数CSV用例来说都是过度杀戮(例如,任何时候你都不担心引用/多行)。
但它会是这样的:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $xml = XML::Twig -> new -> parsefile ( 'template.xml' );
$xml ->set_pretty_print('indented_a');
open ( my $input, '<', 'input.csv' ) or die $!;
while ( <$input> ) {
chomp;
my ( $name, $ip ) = split /,/;
$xml -> root -> set_att('name', $name );
$xml -> get_xpath('//ipaddress',0) -> set_text($ip);
$xml -> print;
}
对于CSV的最后一行,这将生成:
<?xml version="1.0" encoding="UTF-8"?>
<ns0:networkdevice
name="LAB-3"
xmlns:ers="ers.ise.cisco.com"
xmlns:ns0="network.ers.ise.cisco.com"
xmlns:ns1="ers.ise.cisco.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<authenticationSettings>
<enableKeyWrap>true</enableKeyWrap>
<keyEncryptionKey>1234567890123456</keyEncryptionKey>
<keyInputFormat>ASCII</keyInputFormat>
<networkProtocol>RADIUS</networkProtocol>
<radiusSharedSecret>aaa</radiusSharedSecret>
</authenticationSettings>
<coaPort>1700</coaPort>
<NetworkDeviceIPList>
<NetworkDeviceIP>
<ipaddress>10.26.0.3</ipaddress>
<mask>32</mask>
</NetworkDeviceIP>
</NetworkDeviceIPList>
</ns0:networkdevice>
看起来像你之后的样子?
如果您想要将其包含在$xml -> sprint
或类似内容中,那么您需要POST
。