【问题标题】:Insert value from xml file with name spaces to csv file将具有名称空间的 xml 文件中的值插入 csv 文件
【发布时间】:2018-06-24 08:51:09
【问题描述】:

我正在尝试使用 ID 保存 HTTP,例如这个

https://hostname:9060/ers/config/networkdevice/1

在“输出.csv”中。之后,我想在我的获取请求中使用这些链接从管理系统获取有关设备的更多信息。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<ns3:searchResult total="3" xmlns:ns5="ers.ise.cisco.com" xmlns:ers-v2="ers-v2" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns3="v2.ers.ise.cisco.com">
  <ns3:resources>
    <ns5:resource id="1" 
        name="Device1">
        <link rel="self" href="https://hostname:9060/ers/config/networkdevice/1"
        type="application/xml"/>
    </ns5:resource>
    <ns5:resource id="2" 
        name="Device2">
        <link rel="self" href="https://hostname:9060/ers/config/networkdevice/2"
        type="application/xml"/>
    </ns5:resource>
    <ns5:resource id="3" 
        name="Device3">
        <link rel="self" href="https://hostname:9060/ers/config/networkdevice/3"
        type="application/xml"/>
    </ns5:resources>
</ns3:resources>
</ns3:searchResult>

但是使用我的 Perl 脚本后,我的文件是空的。

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use XML::Simple;

#NOTE: Update this to contain my elements  in  CSV      
my @Fields = qw{id};

my $xml = XMLin('Get_All_Prime.xml', ForceArray => ['link']);

foreach my $link ( @{ $xml->{link} } ) { 
    print Dumper $link;

    foreach my $link ( @{ $xml->{link} } ) { 
        print join( ',', @{ $link->{href} }{@Fields} ) . "\n";
    }   
}   

open(my $out, '>', 'output.csv') or die "Output: $!\n";
foreach my $link ( @{ $xml->{link} } ) { 
    print $out join ( ',', @{$link->{href} }{@Fields} ) . "\n";
}

我不确定,我使用了正确的标签

 ForceArray => ['link']

但是在这种情况下我应该使用什么?

【问题讨论】:

标签: xml perl csv parsing


【解决方案1】:

标准的、优秀的 XML 库是 XML::LibXMLXML::Twig

do not use XML::Simple。很久以前它自己的documentation said那个

不鼓励在新代码中使用此模块。

很久以前,它自己的作者写了一个detailed tutorial for XML::LibXML。听从建议。

XML::LibXML 的示例

use warnings;
use strict;
use feature 'say';

use XML::LibXML;

my $file = shift @ARGV || 'Get_All_Prime.xml'

my $reader = XML::LibXML->new();
my $doc = $reader->load_xml(location => $file, no_blanks => 1);

my $xpath = '//ns3:searchResult/ns3:resources/ns5:resource/link';

my @links;
foreach my $node ($doc->findnodes($xpath)) {
    push @links, $node->findvalue('./@href');
}
say for @links;

这里先找到&lt;link ...&gt;元素,作为例子;或者你可以直接去'href'

my $xpath = '//ns3:searchResult/ns3:resources/ns5:resource/link/@href';
foreach my $href ($doc->findnodes($xpath) {
    push @links, $href->to_literal;
}

XML::LibXML 是一个完整的库,完全支持使用XML。请参阅 this postthis post 了解从哪里开始使用其广泛而结构化的文档。


我会冒险并假设所需的 CSV 输出文件包含行 link_url,id

my $outfile = 'output.csv';
open my $fh_out, '>', $outfile or die "Can't open $outfile: $!";
say $fh_out 'url,id';  # header

my $xpath = '//ns3:searchResult/ns3:resources/ns5:resource/link';
my @links;
foreach my $node ($doc->findnodes($xpath)) {
    #say $node->findvalue('./@href'), ' => ', $node->findvalue('../@id');
    push @links, [ map { $node->findvalue($_) } qw(./@href ../@id) ];
}
say $fh_out join ',', @$_  for @links;

要使用 CSV 进行更广泛的工作,请使用 Text::CSVText::CSV_XS 的“瘦包装器”。

【讨论】:

  • @StayCalm 我看不到您需要从链接中提取什么以及应该如何将其放入 CSV,但我希望以上内容可能已经足够好了。如果您确实需要更多详细信息或 CSV 上的内容,请告诉我(请使用该信息编辑问题)。
  • @StayCalm 添加了我猜想要的输出。请用明确的声明编辑问题。
  • 我在 shell 中看到了结果,但我的输出文件只包含没有 https 链接的 Header。我有警告:不能使用字符串(“hostname:9060/ers/conf"...)作为数组参考,而“严格参考”在say $fh_out join ',', @$_ for @links;使用
  • @StayCalm 最后一个代码 sn-p 是从测试脚本中复制出来的。 @$_ 对每个@links 取消引用[ ... ],生成与, 连接的列表。它不应该抛出那个警告,它应该有效吗? (注意,如果您使用第一个(完整)脚本,则不能使用最后一个 sn-p 的最后一行来写入文件——那时它抛出该警告。)
  • @StayCalm 我看到了对问题的编辑,谢谢。澄清一下:它说你想要 url ...仅仅是这样,没有 id 作为单独的 CSV 字段吗? (如果是这样,您不需要此答案中的最后一个代码 sn-p。)
猜你喜欢
  • 1970-01-01
  • 2020-05-22
  • 2012-03-06
  • 1970-01-01
  • 2013-10-09
  • 2021-05-12
  • 1970-01-01
  • 2019-12-17
  • 2019-12-22
相关资源
最近更新 更多