【问题标题】:Perl - Sorting an array of XML query dataPerl - 对一组 XML 查询数据进行排序
【发布时间】:2018-12-06 23:43:43
【问题描述】:

我是 Perl 的新手,我正在尝试从 6 个相似的 XML 中对一组 XML 元素进行排序。下面的代码具有推荐的 6 个文件中的 2 个。我已经尝试了带有子字符串的排序功能,但它还没有工作。任何人都可以检查并帮助我使其工作吗?

use 5.010;
use warnings;
use XML::LibXML;
use XML::XPath;
use XML::XPath::XMLParser;

my $dom1 = XML::XPath->new(filename => './xml/nota1.xml');
my $dom2 = XML::XPath->new(filename => './xml/nota5.xml');

my @list;

foreach my $vProd ($dom1->find('//prod'), $dom2->find('//prod')){
      push @list, $vProd;
}
say @list;

所有 XML 文件都有一个“prod”元素,其中包含有关产品的信息,我想按一个名为“vProd”的元素进行排序。 “vProd”是第九个元素,它是产品在我国货币中的价值。以下是两个 XML 文件:

nota1.xml

<?xml version="1.0" encoding="UTF-8"?>
<list>
    <prod>
        <cProd>025-1220-318-40</cProd>
        <cEAN>4051411545402</cEAN>
        <xProd>Chuteira Puma Esito Finale IT</xProd>
        <NCM>64029990</NCM>
        <CFOP>6108</CFOP>
        <uCom>PAR</uCom>
        <qCom>1</qCom>
        <vUnCom>94.91</vUnCom>
        <vProd>94.91</vProd>
        <cEANTrib>4051411545402</cEANTrib>
        <uTrib>PAR</uTrib>
        <qTrib>1</qTrib>
        <vUnTrib>94.91</vUnTrib>
        <indTot>1</indTot>
    </prod>
</list>

nota5.xml

<?xml version="1.0" encoding="UTF-8"?>
<list>
    <prod>
        <cProd>AEMC815BZA</cProd>
        <cEAN>0885909455232</cEAN>
        <xProd>MAC MINI COREI5 2GB500GB | 0885909455232| Rua: A</xProd>
        <NCM>84715010</NCM>
        <CFOP>5929</CFOP>
        <uCom>PC</uCom>
        <qCom>1.0000</qCom>
        <vUnCom>1606.0000</vUnCom>
        <vProd>1606.00</vProd>
        <cEANTrib>0885909455232</cEANTrib>
        <uTrib>PC</uTrib>
        <qTrib>1.0000</qTrib>
        <vUnTrib>1606.0000</vUnTrib>
        <indTot>1</indTot>
    </prod>
    <prod>
        <cProd>AEMD032BZA</cProd>
        <cEAN>0885909480920</cEAN>
        <xProd>ROTEADOR TIME CAPSULE 2TB BCO | 0885909480920| Rua: A</xProd>
        <NCM>84717019</NCM>
        <CFOP>5929</CFOP>
        <uCom>PC</uCom>
        <qCom>1.0000</qCom>
        <vUnCom>852.0000</vUnCom>
        <vProd>852.00</vProd>
        <cEANTrib>0885909480920</cEANTrib>
        <uTrib>PC</uTrib>
        <qTrib>1.0000</qTrib>
        <vUnTrib>852.0000</vUnTrib>
        <indTot>1</indTot>
    </prod>
</list>

提前致谢!

【问题讨论】:

  • 你看过perldoc.perl.org/… 吗?该常见问题解答如何无法回答您的问题?
  • @Corion 我的错,我只尝试在谷歌和这里搜索,但我没有找到那个页面。不过,我仍然无法让它适用于我的情况。
  • @ikegami 你是对的,再次抱歉。我希望现在已经足够好了。

标签: xml perl


【解决方案1】:

首先,让我们构建 prod 元素列表:

use XML::LibXML;

my @qfns = ( 'xml/nota1.xml', 'xml/nota5.xml', ... );

my @prod_eles;
for my $qfn (@qfns) {
    my $doc = XML::LibXML->load_xml( location => $qfn );
    push @prod_eles, $doc->findnodes('/list/prod');
}

我使用 XML::LibXML 是因为我很熟悉它,它非常快、非常可靠,并且因为您正在加载它(即使您不使用它)。

现在,我们只需对元素进行排序。你的情况没有什么特别的。使用 XPath,我们可以轻松地在对象中查询我们想要比较的值。

@prod_eles =
   sort { $a->findvalue('vProd') <=> $b->findvalue('vProd') }
      @prod_eles;

为了加快速度,我们还可以使用以下代码:

use Sort::Key qw( nkeysort );

@prod_eles =
   nkeysort { $_->findvalue('vProd') }
      @prod_eles;

【讨论】:

  • 非常感谢,成功了!抱歉这么久才回答。很遗憾,目前无法投票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-17
  • 2011-07-06
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多