我正在尝试使用SOAP::Lite编写一个简单的SOAP客户端。在发出请求之后,响应似乎只被解析为perl数据结构几个级别。之后,它只是剩下的XML的一串。我觉得获取该字符串并使用另一个XML解析器手动解析它会非常麻烦。
my $response = $soap->getVersionInfo;
my $data = $response->dataof('//getVersionInfoResponse');
SOAP响应在SOAP :: Lite跟踪中如下所示:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:getVersionInfoResponse xmlns:ns="http://webservice.jchem.chemaxon">
<ns:return>
<Info>
<JChem>
<Version>5.2.6</Version>
</JChem>
<Java>
<Vendor>Sun Microsystems Inc.</Vendor>
<VmName>Java HotSpot(TM) Client VM</VmName>
<Version>1.6.0_05</Version>
</Java>
<Os>
<Arch>x86</Arch>
<Name>Windows XP</Name>
<Version>5.1</Version>
</Os>
</Info>
</ns:return>
</ns:getVersionInfoResponse>
</soapenv:Body>
</soapenv:Envelope>
但是解析成$data
的内容看起来像这样(来自Data :: Dumper :: Concise):
\bless( {
_attr => {},
_name => "getVersionInfoResponse",
_prefix => "ns",
_signature => [],
_uri => "http://webservice.jchem.chemaxon",
_value => [
{
return => "<Info>\n<JChem>\n<Version>5.2.6</Version>\n</JChem>\n<Java>\n<Vendor>Sun Microsystems Inc.</Vendor>\n<VmName>Java HotSpot(TM) Client VM</VmName>\n<Version>1.6.0_05</Version>\n</Java>\n<Os>\n<Arch>x86</Arch>\n<Name>Windows XP</Name>\n<Version>5.1</Version>\n</Os>\n</Info>\n"
}
]
}, 'SOAP::Data' )
这是一个简单的示例,但对于更复杂的响应,必须解析该XML可能会变得非常麻烦。
我在SOAP :: Lite邮件列表上找到了this post(从2003年开始!),上面有一个令人担忧的引用:
请记住任何要求 SOAP本身不知道的属性 必须是名称空间限定的。
我注意到未解析的所有内容都没有命名空间。有没有办法强制SOAP :: Lite解析那个非命名空间的xml?这甚至是问题吗?
更新:
事实证明,SOAP :: Lite正在做正确的事情。我忽略了服务文档中的一条说明
注意:里面的特殊字符
<ns:return>
标记已编码为 实体。 (例如xml返回值 将包含&lt;人物,会 被编码为<
个实体)因此 需要实体解码 客户方。
我认为只是跟踪输出不一致实际上是问题所在。 SOAP :: Lite很好,并且在它们最终进入Dumper之前对实体进行转移也使我感到困惑。我最初包含了文档的示例,因为它已经很好地格式化了。现在显示实际输出。另外,每个人都知道<
与&lt;相同,对吧?对? ; _;
截至目前,我正在使用XML :: LibXML解析字符串,所以问题仍然存在。我是否可以强制SOAP :: Lite解析内部XML字符串,即使它已被转义?
答案 0 :(得分:4)
适合我; $response->result
为Info元素提供所有子项:
{
Info => {
JChem => {
Version => "5.2.1"
},
Java => {
Vendor => "Sun Microsystems Inc.",
Version => "1.6.0_06",
VmName => "Java HotSpot(TM) Server VM"
},
Os => {
Arch => "x86",
Name => "Windows XP",
Version => "5.1"
}
}
}
而$response->dataof('//getVersionInfoResponse')
会返回一个完整深度的树。
你在运行什么版本的Soap :: Lite?我正在使用0.710.10:
$sudo perl -MCPAN -e shell
cpan[6]> i SOAP:Lite
...
INST_VERSION 0.710.10
答案 1 :(得分:0)
根据我在SOAP :: Lite邮件列表(post)上学到的内容,SOAP :: Lite的目的是仅处理协议和信封,而不是消息的内部。我最终使用XML::Simple来解析响应的内容。