无法以Perl获取交易的最高版本
我刚刚开始学习Perl,陷入了不稳定的局面。输入源XML文件为:无法以Perl获取交易的最高版本,perl,xml-twig,Perl,Xml Twig,我刚刚开始学习Perl,陷入了不稳定的局面。输入源XML文件为: <STATEMENT> <TRADE origin = "BANK", ref="1",version="1"> <EVENT type="PRO"> <EVENTNAR key = "USE" val = "MY"/> <EVENTNAR key = "USEE" val = "MYY"/> </EVE
<STATEMENT>
<TRADE origin = "BANK", ref="1",version="1">
<EVENT type="PRO">
<EVENTNAR key = "USE" val = "MY"/>
<EVENTNAR key = "USEE" val = "MYY"/>
</EVENT>
</TRADE>
<TRADE origin = "BANK", ref="1",version="2">
<EVENT type="PRO">
<EVENTNAR key = "USE" val = "MYY"/>
<EVENTNAR key = "USEE" val = "MYY"/>
</EVENT>
</TRADE>
<TRADE origin = "BANK", ref="2",version="1">
<EVENT type="PRO">
<EVENTNAR key = "USE" val = "MY"/>
<EVENTNAR key = "USEE" val = "MYY"/>
</EVENT>
<TRADE origin = "BANK" ref="1",version="1">
<EVENT type="PRO">
<EVENTNAR key = "USE" val = "MY"/>
<EVENTNAR key = "USEE" val = "MYY"/>
</EVENT>
</TRADE>
</TRADE>
<STATEMENT>
我的输出是:
<STATEMENT>
<TRADE origin = "BANK", ref="1",version="1">(this shouldn't come )
<EVENT type="PRO">
<EVENTNAR key = "USE" val = "MY"/>
<EVENTNAR key = "USEE" val = "MYY"/>
</EVENT>
</TRADE>
<TRADE origin = "BANK", ref="1",version="2">
<EVENT type="PRO">
<EVENTNAR key = "USE" val = "MYY"/>
<EVENTNAR key = "USEE" val = "MYY"/>
</EVENT>
</TRADE>
<TRADE origin = "BANK", ref="2",version="1">
<EVENT type="PRO">
<EVENTNAR key = "USE" val = "MY"/>
<EVENTNAR key = "USEE" val = "MYY"/>
</EVENT>
</TRADE>
</STATEMENT>
(这不应该发生)
可以看出,给定ref的最高版本的逻辑不起作用
如果您有任何建议,我们将不胜感激。在修复输入后使用:
open file.xml ;
rm //TRADE/TRADE ;
$l = //TRADE[@origin='BANK'][EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]] ;
$h := hash @ref $l ;
for my $ref in { keys %$h } {
$trades = xsh:lookup('h', $ref);
ls $trades[@version=xsh:max($trades/@version)] ;
} | cat > output1.xml ;
对于非常大的文件,您可以尝试使用流媒体接口:
$h = { {} } ;
stream :f file.xml :F /dev/null select TRADE {
rm TRADE ;
if (@origin='BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
) {
$ref = @ref ;
$record = xsh:lookup('h', $ref)/@version ;
perl { $record ||= -1 } ;
if (@version > $record) {
$here = . ;
perl { $h->{$ref} = $here } ;
}
}
} ;
create STATEMENT ;
for my $trade in { values %$h } mv $trade into STATEMENT ;
save :f output2.xml ;
在MSWin上,您必须使用NUL
而不是/dev/null
。程序仍然可能内存不足-它需要记住整个输出。如果太多,您必须更改它以处理文件两次:在第一次运行时,它将记住每个ref的最大版本,在第二次运行时,它将输出
$h = { {} } ;
stream :f file.xml :F /dev/null select TRADE {
rm TRADE ;
if (@origin='BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
) {
$ref = @ref ;
$record = xsh:lookup('h', $ref) ;
perl { $record ||= -1 } ;
if (@version > $record) {
$record = @version ;
perl { $h->{$ref} = $record } ;
}
}
} ;
stream :f file.xml :F output3.xml select TRADE {
rm TRADE ;
if not(@origin = 'BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
and xsh:lookup('h', @ref) = @version
) rm . ;
} ;
如果版本+参考组合是唯一的,则在修复输入后,您可以使用以下方法简化最后一次中的条件(如果不是):
open file.xml ;
rm //TRADE/TRADE ;
$l = //TRADE[@origin='BANK'][EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]] ;
$h := hash @ref $l ;
for my $ref in { keys %$h } {
$trades = xsh:lookup('h', $ref);
ls $trades[@version=xsh:max($trades/@version)] ;
} | cat > output1.xml ;
对于非常大的文件,您可以尝试使用流媒体接口:
$h = { {} } ;
stream :f file.xml :F /dev/null select TRADE {
rm TRADE ;
if (@origin='BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
) {
$ref = @ref ;
$record = xsh:lookup('h', $ref)/@version ;
perl { $record ||= -1 } ;
if (@version > $record) {
$here = . ;
perl { $h->{$ref} = $here } ;
}
}
} ;
create STATEMENT ;
for my $trade in { values %$h } mv $trade into STATEMENT ;
save :f output2.xml ;
在MSWin上,您必须使用NUL
而不是/dev/null
。程序仍然可能内存不足-它需要记住整个输出。如果太多,您必须更改它以处理文件两次:在第一次运行时,它将记住每个ref的最大版本,在第二次运行时,它将输出
$h = { {} } ;
stream :f file.xml :F /dev/null select TRADE {
rm TRADE ;
if (@origin='BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
) {
$ref = @ref ;
$record = xsh:lookup('h', $ref) ;
perl { $record ||= -1 } ;
if (@version > $record) {
$record = @version ;
perl { $h->{$ref} = $record } ;
}
}
} ;
stream :f file.xml :F output3.xml select TRADE {
rm TRADE ;
if not(@origin = 'BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
and xsh:lookup('h', @ref) = @version
) rm . ;
} ;
如果版本+参考组合是唯一的,则在修复输入后,您可以使用以下方法简化最后一次中的条件(如果不是):
open file.xml ;
rm //TRADE/TRADE ;
$l = //TRADE[@origin='BANK'][EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]] ;
$h := hash @ref $l ;
for my $ref in { keys %$h } {
$trades = xsh:lookup('h', $ref);
ls $trades[@version=xsh:max($trades/@version)] ;
} | cat > output1.xml ;
对于非常大的文件,您可以尝试使用流媒体接口:
$h = { {} } ;
stream :f file.xml :F /dev/null select TRADE {
rm TRADE ;
if (@origin='BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
) {
$ref = @ref ;
$record = xsh:lookup('h', $ref)/@version ;
perl { $record ||= -1 } ;
if (@version > $record) {
$here = . ;
perl { $h->{$ref} = $here } ;
}
}
} ;
create STATEMENT ;
for my $trade in { values %$h } mv $trade into STATEMENT ;
save :f output2.xml ;
在MSWin上,您必须使用NUL
而不是/dev/null
。程序仍然可能内存不足-它需要记住整个输出。如果太多,您必须更改它以处理文件两次:在第一次运行时,它将记住每个ref的最大版本,在第二次运行时,它将输出
$h = { {} } ;
stream :f file.xml :F /dev/null select TRADE {
rm TRADE ;
if (@origin='BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
) {
$ref = @ref ;
$record = xsh:lookup('h', $ref) ;
perl { $record ||= -1 } ;
if (@version > $record) {
$record = @version ;
perl { $h->{$ref} = $record } ;
}
}
} ;
stream :f file.xml :F output3.xml select TRADE {
rm TRADE ;
if not(@origin = 'BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
and xsh:lookup('h', @ref) = @version
) rm . ;
} ;
如果版本+参考组合是唯一的,则在修复输入后,您可以使用以下方法简化最后一次中的条件(如果不是):
open file.xml ;
rm //TRADE/TRADE ;
$l = //TRADE[@origin='BANK'][EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]] ;
$h := hash @ref $l ;
for my $ref in { keys %$h } {
$trades = xsh:lookup('h', $ref);
ls $trades[@version=xsh:max($trades/@version)] ;
} | cat > output1.xml ;
对于非常大的文件,您可以尝试使用流媒体接口:
$h = { {} } ;
stream :f file.xml :F /dev/null select TRADE {
rm TRADE ;
if (@origin='BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
) {
$ref = @ref ;
$record = xsh:lookup('h', $ref)/@version ;
perl { $record ||= -1 } ;
if (@version > $record) {
$here = . ;
perl { $h->{$ref} = $here } ;
}
}
} ;
create STATEMENT ;
for my $trade in { values %$h } mv $trade into STATEMENT ;
save :f output2.xml ;
在MSWin上,您必须使用NUL
而不是/dev/null
。程序仍然可能内存不足-它需要记住整个输出。如果太多,您必须更改它以处理文件两次:在第一次运行时,它将记住每个ref的最大版本,在第二次运行时,它将输出
$h = { {} } ;
stream :f file.xml :F /dev/null select TRADE {
rm TRADE ;
if (@origin='BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
) {
$ref = @ref ;
$record = xsh:lookup('h', $ref) ;
perl { $record ||= -1 } ;
if (@version > $record) {
$record = @version ;
perl { $h->{$ref} = $record } ;
}
}
} ;
stream :f file.xml :F output3.xml select TRADE {
rm TRADE ;
if not(@origin = 'BANK'
and EVENT[@type='PRO'][EVENTNAR[@key='USE'][@val='MY']]
and xsh:lookup('h', @ref) = @version
) rm . ;
} ;
如果version+ref组合是唯一的,您可以简化最后一个中的条件,如果不是您的xml
格式不正确。属性之间不能有逗号,并且您忘记关闭
。更高版本的交易不符合条件4。如果多个交易
元素的版本号最高,会发生什么情况?@borodin-在这种情况下,所有交易都会在那里…@choroba-它会出现..如果您看到一组evennar是正确的…也就是说足以选择交易您的xml
格式不正确。属性之间不能有逗号,并且您忘记关闭
。更高版本的交易不符合条件4。如果多个交易
元素的版本号最高,会发生什么情况?@borodin-在这种情况下,所有交易都会在那里…@choroba-它会出现..如果您看到一组evennar是正确的…也就是说足以选择交易您的xml
格式不正确。属性之间不能有逗号,并且您忘记关闭
。更高版本的交易不符合条件4。如果多个交易
元素的版本号最高,会发生什么情况?@borodin-在这种情况下,所有交易都会在那里…@choroba-它会出现..如果您看到一组evennar是正确的…也就是说足以选择交易您的xml
格式不正确。属性之间不能有逗号,并且您忘记关闭
。更高版本的交易不符合条件4。如果多个交易
元素的版本号最高,会发生什么情况?@borodin-在这种情况下,所有交易都会在那里…@choroba-它会出现..如果您看到一组evennar是正确的…也就是说根据OP前面的问题,该文件可能非常大,足以选择交易。这是否需要将整个文件加载到内存中?@mirod:不幸的是,是的。稍后我可以想到使用流媒体接口的解决方案:-)@mirod:给你。@karanarora:算法应该类似。您必须处理整个文件以获得每个参考的最大值或解决方案。根据OP前面的问题,文件可能非常大。这是否需要将整个文件加载到内存中?@mirod:不幸的是,是的。稍后我可以想到使用流媒体接口的解决方案:-)@mirod:给你。@karanarora:算法应该类似。您必须处理整个文件以获得每个参考的最大值或解决方案。根据OP前面的问题,文件可能非常大。这是否需要将整个文件加载到内存中?@mirod:不幸的是,是的。稍后我可以想到使用流媒体接口的解决方案:-)@mirod:给你。@karanarora:算法应该类似。您必须处理整个文件以获得每个参考的最大值或解决方案。根据OP前面的问题,文件可能非常大。这是否需要将整个文件加载到内存中?@mirod:不幸的是,是的。稍后我可以想到使用流媒体接口的解决方案:-)@mirod:给你。@karanarora:算法应该类似。您必须处理整个文件,以获得每个参考的最大值或解决方案。