Perl XML :: LibXML与SOAP :: SOM

时间:2014-03-23 18:51:13

标签: xml perl soap xml-parsing libxml2

我有一个XML字符串,我使用LibXMLfindnodes& textContent,这很有效:

#!/usr/bin/perl -w

use strict;
use warnings;

use SOAP::Lite 0.715;
use Data::Dumper;
use XML::LibXML qw();

my $cust_xml  = '<?xml version="1.0" standalone="yes"?>
<CUSTOMER_RESPONSE>
  <CUSTOMER>
    <TEL>555-555-5555</TEL>
  </CUSTOMER>
  <PRODUCTS>
    <PRODUCT>
      <PRODUCT_ID>Apple</PRODUCT_ID>
    </PRODUCT>
    <PRODUCT>
      <PRODUCT_ID>BlackBerry</PRODUCT_ID>
    </PRODUCT>
    <PRODUCT>
      <PRODUCT_ID>Orange</PRODUCT_ID>
    </PRODUCT>
  </PRODUCTS>
</CUSTOMER_RESPONSE>
';

my $dom = XML::LibXML->load_xml(string => $cust_xml);
for my $productNode ($dom->findnodes('//PRODUCT_ID')) {
    my $product_id = $productNode->textContent;
    print STDERR "id=$product_id\n";
}

我的目标计算机(HP-UX上的Perl 5.8.8)不包含XML::LibXML,我希望我可以使用SOAP::SOM实现相同目标。但是,我似乎无法获得正确的语法:

my $som = SOAP::SOM->new($cust_xml);
for my $productNode ($som->valueof('//PRODUCTS/PRODUCT')) {
    my $product_id = $productNode->{'PRODUCT_ID'};
    print STDERR "id=$product_id\n";
}

当我运行上面的代码片段时,出现运行时错误:

% ./som.pl
Can't use string ("<?xml version="1.0" standalone=""...) as an ARRAY ref while "strict refs" in use at /Users/<username>/perl5/lib/perl5/SOAP/Lite.pm line 391.

您是否有任何建议,甚至推荐可能在旧机器上找到的其他通用库?

-hq

1 个答案:

答案 0 :(得分:3)

这是解析XML的一种非常奇怪的方法。是否没有其他有效的XML模块可供使用,例如XML::Twig

SOAP::SOM期望参数中的裸XML不仅仅是其构造函数。它通常是通过使用SOAP::Lite访问远程SOAP服务器来创建的。

您需要使用SOM::Deserializer,就像这样

use strict;
use warnings;

use SOAP::Lite;

my $cust_xml  = <<'__END_XML__';
<CUSTOMER_RESPONSE>
  <CUSTOMER>
    <TEL>555-555-5555</TEL>
  </CUSTOMER>
  <PRODUCTS>
    <PRODUCT>
      <PRODUCT_ID>Apple</PRODUCT_ID>
    </PRODUCT>
    <PRODUCT>
      <PRODUCT_ID>BlackBerry</PRODUCT_ID>
    </PRODUCT>
    <PRODUCT>
      <PRODUCT_ID>Orange</PRODUCT_ID>
    </PRODUCT>
  </PRODUCTS>
</CUSTOMER_RESPONSE>
__END_XML__

my $som = SOAP::Deserializer->deserialize($cust_xml);

print "$_\n" for $som->valueof('//PRODUCT_ID');

<强>输出

Apple
BlackBerry
Orange