xml - 在 Perl 中将类似 XML 的格式转换为 CSV
问题描述
所以,我有一个看起来像这样的文件:
random stuff in the beginning...
<component>
<name>bob</name>
<age>7</age>
<country>Great_Britain</country>
</component>
<component>
<name>bob_secondbob</name>
<age>7</age>
<country>Great_Britain</country>
</component>
<component>
<name>bam</name>
<age>7</age>
<country>Great_Britain</country>
</component>
ETC...
而且,我只想将其作为 CSV 文件,如下所示:
name,age,country
bob,7,Great_Britain
bob_secondbob,7,Great_Britain
bam,7,Great_Britain
所以我想知道我该怎么做呢?
所以我当前的代码有类似bob
and的词bam
,所以我一直在寻找它,并使用 sed 来获取值:
grep -A4 "<component>" $file | grep -A4 "<name>$bob.*</name>" | grep "<name>"
grep -A4 "<component>" $file | grep -A4 "<name>$bob.*</name>" | grep "<age>"
grep -A4 "<component>" $file | grep -A4 "<name>$bob.*</name>" | grep "<country>"
etc...
变量在$bob
哪里"bob"
;
但问题是有 2 个实例,bob.*
我不知道如何将它们分开,所以我可以将它们打印出来......
我查看了 XML 模块,但这个文件不完全是 XML,所以我不能使用它......
像bam
这样通过grep很容易打印出来,但是如果有多个bob.*
我需要它们的实例,idk如何正确打印它,因为grep会返回多个结果。
关于我如何解决这个问题的任何建议?
解决方案
明确指出“文件不是完全的 XML ”,不能使用 XML 库。无赖:(
然后使用正则表达式对其进行解析。请记住,必须始终关注输入文件以查看其格式是否发生了变化;即使是最小的更改也很容易导致正则表达式失效,最多导致程序崩溃,或者更糟糕的是,导致一个安静的错误。†</sup>
显示的格式很容易解析。component
这是一个基本步骤,解析任何标签及其值的类似 XML 的部分,然后按需要的顺序打印给定的一组实际标签。
use warnings;
use strict;
use feature 'say';
my $section_name = 'component'; # XML-like section to parse
my @tags = qw(name age country); # given tags and their order
my (%record, $in_XML);
while (<>) {
if (/^\s*<$section_name>\s*$/) { $in_XML = 1 }
elsif (/^\s*<\/$section_name>\s*$/) { $in_XML = 0 }
if ( $in_XML and m{<([^<]+)> ([^<]+) </\g{1}>}x ) {
push @{$record{$1}}, $2;
}
}
# Print out CSV-style output, with given tags
say join ',', @tags;
for my $i (0..$#{$record{$tags[0]}}) {
say join ',', map { $record{$_}->[$i] } @tags;
}
对标签做了一些假设。一些重要的:每个标签对都在一行上;所有标签名称都是唯一的。如果这些不包含需要调整的代码,可以做什么但需要一些工作。
除了匹配类似 XML 的开始和结束标记对之外,<tagname>...</tagname>
我还添加了一个标志,用于处理何时在一个component
部分内。在条件内测试标志if
允许在 XML 之外进行其他处理,否则我们可以在条件next if not $in_XML;
之前进行if
。如果没有机会在文本的其他地方出现意外的类似 XML 的标记对,那么整个业务可能是不必要的。
请注意,不必指定和使用,@tags
但可以打印文件中找到的标签my @tags = keys %record
,如果可以接受并且顺序无关紧要,则可以打印。
请添加测试这些标签及其值是否确实是人们所期望的。现实的输入文件往往偶尔会有缺失或意外的部分。
†</sup> 如果可能的话,纠正“不是完全 XML ”(使其成为 XML)并使用库会好得多。
推荐阅读
- c++ - 加载共享库时出错:libboost_program_options.so.1.65.1
- java - Java regex - 首先需要是字母 X(不区分大小写)其余数字
- python - 稀疏行矩阵会有助于此代码的计算速度吗?
- bash - 使用分隔符将多个文件合并到一个单行文件中
- python - Mac Pycharm 解释器不工作
- c# - c# mvc - 授权ajax函数
- database - ArangoDB 中的一对一和一对多数据格式
- r - 字符向量中的两个 PASTE 函数
- ansible - Ansible 标准循环不工作
- localhost - 让 WAMPSERVER 在线但隐藏其服务器的索引文件