代码之家  ›  专栏  ›  技术社区  ›  wes

我可以在SOAP::Lite中强制进一步的XML解析吗?

  •  3
  • wes  · 技术社区  · 15 年前

    我正在尝试使用 SOAP::Lite .在发出请求之后,响应似乎只被解析为几个级别以下的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>
                &lt;Info>
                &lt;JChem>
                &lt;Version>5.2.6&lt;/Version>
                &lt;/JChem>
                &lt;Java>
                &lt;Vendor>Sun Microsystems Inc.&lt;/Vendor>
                &lt;VmName>Java HotSpot(TM) Client VM&lt;/VmName>
                &lt;Version>1.6.0_05&lt;/Version>
                &lt;/Java>
                &lt;Os>
                &lt;Arch>x86&lt;/Arch>
                &lt;Name>Windows XP&lt;/Name>
                &lt;Version>5.1&lt;/Version>
                &lt;/Os>
                &lt;/Info>
             </ns:return>
          </ns:getVersionInfoResponse>
       </soapenv:Body>
    </soapenv:Envelope>
    

    但是被分析的东西 $data 如下所示(来自data::dumper::conformit):

    \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可能会成为一个巨大的麻烦。

    我发现 this post 在SOAP::Lite邮件列表上(2003年起!)上面有句令人担忧的话:

    记住以下要求: SOAP本机不知道的属性 必须是命名空间限定的。

    我注意到所有未解析的内容都没有命名。有没有一种方法可以强制soap::lite解析该非名称空间XML?这就是问题所在吗?

    更新:
    结果是soap::lite做了正确的事情。我忽略了服务文档中的一条说明

    注释 :里面的特殊字符 <ns:return> 标记编码为 实体。(例如,XML返回值 将包含<个字符,这将 被编码为 &lt; 实体)因此 在上需要实体解码 客户端。

    我认为跟踪输出不一致实际上是问题所在。在实体最终被丢进垃圾箱之前,对它们的友好和疏远也让我困惑。我最初包括了文档的示例,因为它的格式已经很好了。现在显示实际输出。另外,大家都知道 &书信电报; 与<相同,对吗?正确的?;

    到目前为止,我正在用xml::libxml解析字符串,所以这个问题仍然存在。我是否可以强制soap::lite解析该内部XML字符串,即使它已被转义?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Andomar    15 年前

    对我来说工作很好; $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
    
        2
  •  0
  •   wes    15 年前

    从我在soap::lite邮件列表上学到的东西( post ,soap::lite的目的是只处理协议和信封,而不是消息的内部。我最后用了 XML::Simple 解析响应的内容。