我正在使用Perl和XML :: LibXML,我必须处理的XML看起来像这样:
<PARAM NAME = "A"><VALUE>1</VALUE>
<PARAM NAME = "B"><VALUE>3</VALUE>
<PARAM NAME = "C"><VALUE>43</VALUE>
<PARAM NAME = "A"><VALUE>6</VALUE>
<PARAM NAME = "B"><VALUE>3</VALUE>
<PARAM NAME = "C"><VALUE>13</VALUE>
.
.
.
我需要的输出基本上是:
A B C
1 3 43
6 3 13
我把文字节点名称放到这样的数组中:
my @attributes = (
'./PARAM[@NAME = "A"]/VALUE',
'./PARAM[@NAME = "B"]/VALUE',
.
.
);
然后使用findnodes()和findvalue()将这些xpath文字作为foreach循环中的参数,错误地尝试获取值的'set',以写入记录。 当然,findnodes()是错误的,因为它通过循环获得满足条件的所有节点(正如它应该做的那样),而findvalues()是错误的,因为它实际上做同样的事情,只是连接所有类似的 - 命名节点值。
由于这个文件的结构是这样的,我看不到捕获'A thru C'节点/值,写一条记录,然后重复...至少没有检查每个节点,看它是不是'最后一个'('C')。似乎我需要将其作为一个普通的旧文本文件处理,基本上。
答案 0 :(得分:0)
你没有提供你正在使用的语言,但它似乎是perl。基本上,获取所有<VALUE/>
个元素(分别是它们的文本节点)然后循环遍历它们,每次读取三个值。
有点像peroc的伪代码:
@attributes = xpath('//PARAM/VALUE');
for ($i = 0; i < length(@attributes); i += 3)
push @records (@attributes[$i], @attributes[$i + 1], @attributes[$i + 2])
结果,你应该得到一个数组数组(当然你也可以返回一个哈希数组)。如果您只想要输出,请使用上面的模式,并调用printf
而不是push
。
答案 1 :(得分:0)
这是我采取的一种方法:
foreach my $parameter ( $raid_group->findnodes('PARAM')) {
my $name = $parameter->findvalue('@NAME);
my $value = $parameter->findvalue('VALUE');
if ($name eq $first_name_in_set ){
[do stuff]
}
}
这是一个使用螺丝刀做凿子的情况我认为 - 权宜之计但不多。
答案 2 :(得分:0)
您的数据实际上并不是有效的XML,因为每个PARAM都没有结束标记。因此,您需要在运行XML Parser之前清理数据,或者使用正则表达式。
以下使用正则表达式来解析任意数量的字段和值:
use strict;
use warnings;
my %seen_header;
my @headers;
my @data = {};
while (<DATA>) {
if (m{<PARAM NAME = "(.*?)"><VALUE>(.*?)</VALUE>}i) {
my $name = $1;
my $val = $2;
push @headers, $name if ! $seen_header{$name}++;
push @data, {} if exists $data[-1]{$name};
$data[-1]{$name} = $val;
} else {
warn "Unrecognized format at line $.: $_"
}
}
print "@headers\n";
print join(' ', map {$_ // ''} @{$_}{@headers}), "\n" for (@data);
__DATA__
<PARAM NAME = "A"><VALUE>1</VALUE>
<PARAM NAME = "B"><VALUE>3</VALUE>
<PARAM NAME = "C"><VALUE>43</VALUE>
<PARAM NAME = "A"><VALUE>6</VALUE>
<PARAM NAME = "B"><VALUE>3</VALUE>
<PARAM NAME = "C"><VALUE>13</VALUE>
输出:
A B C
1 3 43
6 3 13
还可以修改此代码以使用XML Parser,但如果它是你想要的,我会把它留给你。