将单文本文件中的多段XML转换为CSV的Perl实现问题
处理多段XML文本并转换为CSV的Perl解决方案
我明白你的问题了——你的输入文件里是多个独立的<queryResponse> XML片段,不是单个完整的XML文档,而原来的代码只处理单个XML文件,所以没法正确解析这些多段内容。下面是修改后的Perl代码,专门适配这种场景:
修改后的完整代码
#!/usr/bin/perl use strict; use warnings; use XML::Simple; # 定义要输出到CSV的目标字段 my @Fields = qw{clearedAlarms warningAlarms}; # 打开并初始化输出CSV文件 open(my $out_fh, '>', 'test.csv') or die "无法打开输出文件: $!"; print $out_fh join(', ', @Fields) . "\n"; # 读取包含多段XML的输入文件内容 open(my $in_fh, '<', 'test.txt') or die "无法打开输入文件: $!"; local $/; # 取消行分隔符,一次性读取整个文件 my $content = <$in_fh>; close $in_fh; # 拆分出每个独立的<queryResponse>XML块 # 正则表达式匹配完整响应节点,/s修饰符让.匹配换行符 my @xml_blocks = split /(<queryResponse>.*?<\/queryResponse>)/s, $content; # 过滤掉空字符串和非XML块的冗余内容 @xml_blocks = grep { /^<queryResponse>/ } @xml_blocks; # 遍历每个XML块进行解析和数据提取 foreach my $block (@xml_blocks) { # 解析单个XML块,ForceArray确保entity始终是数组(兼容单/多entity场景) my $xml = XMLin($block, ForceArray => ['entity']); foreach my $entity (@{ $xml->{entity} }) { # 从devicesDTO中提取指定字段值,拼接为CSV行 my @values = map { $entity->{devicesDTO}->{$_} // '' } @Fields; print $out_fh join(', ', @values) . "\n"; } } close $out_fh;
关键改动说明
- 拆分多段XML:先读取整个文件内容,用正则表达式精准拆分出每个完整的
<queryResponse>块,解决了原代码只能处理单个XML文档的核心问题。 - 逐个解析片段:对每个拆分出来的XML块单独调用
XMLin解析,确保每个片段都能被正确识别。 - 鲁棒性优化:用
map配合// ''处理字段缺失的情况(如果某个字段不存在,会输出空值,可根据需求调整);添加过滤步骤避免无效内容干扰解析。
测试效果
用你提供的示例输入文本运行代码后,test.csv的内容会完全符合你的预期:
clearedAlarms, warningAlarms 1, 0 2, 2
内容的提问来源于stack exchange,提问作者pgoose231989
相关产品推荐
相关产品推荐

