Php 如何在没有SoapClient的情况下解析SOAP响应

Php 如何在没有SoapClient的情况下解析SOAP响应,php,xml,soap,Php,Xml,Soap,在过去的几天里,我一直在尝试解析SOAP响应,但我无法让它工作。我希望能够得到所有的OpProduct对象 编辑:我这样做,而不是使用内置的SOAP客户端,因为我需要使用multi_curl执行并行请求 这是我的密码: $xml = simplexml_load_string($response); $xml->registerXPathNamespace('soap-env', 'http://schemas.xmlsoap.org/soap/envelope/'); foreach (

在过去的几天里,我一直在尝试解析SOAP响应,但我无法让它工作。我希望能够得到所有的OpProduct对象

编辑:我这样做,而不是使用内置的SOAP客户端,因为我需要使用multi_curl执行并行请求

这是我的密码:

$xml = simplexml_load_string($response);
$xml->registerXPathNamespace('soap-env', 'http://schemas.xmlsoap.org/soap/envelope/');
foreach ($xml->xpath('//oproduct') as $item)
{
  // do something
}
以下是答复:

<soap-env:envelope xmlns:ns1="http://v3.core.com.productserve.com/" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
  <soap-env:body>
    <ns1:getproductlistresponse>
      <oproduct>
        <iid>113133802</iid>
        <icategoryid>270</icategoryid>
        <imerchantid>1547</imerchantid>
        <iadult>0</iadult>
        <sname>The Ashes / 5th Test - England v Australia - Day 1</sname>
        <sawdeeplink>http://www.awin1.com/pclick.php?p=113133802&amp;a=111402&amp;m=1547&amp;platform=cs</sawdeeplink>
        <sawthumburl>http://images.productserve.com/thumb/1547/113133802.jpg</sawthumburl>
        <fprice>119.99</fprice>
      </oproduct>
      <oproduct>
        <iid>113133791</iid>
        <icategoryid>270</icategoryid>
        <imerchantid>1547</imerchantid>
        <iadult>0</iadult>
        <sname>The Ashes / 1st Test - England v Australia - Day 1</sname>
        <sawdeeplink>http://www.awin1.com/pclick.php?p=113133791&amp;a=111402&amp;m=1547&amp;platform=cs</sawdeeplink>
        <sawthumburl>http://images.productserve.com/thumb/1547/113133791.jpg</sawthumburl>
        <fprice>69.99</fprice>
      </oproduct>
      <oproduct>
        <iid>51155349</iid>
        <icategoryid>428</icategoryid>
        <imerchantid>513</imerchantid>
        <iadult>0</iadult>
        <sname>Rapitest DTM 118 Damp Test Meter</sname>
        <sawdeeplink>http://www.awin1.com/pclick.php?p=51155349&amp;a=111402&amp;m=513&amp;platform=cs</sawdeeplink>
        <sawthumburl>http://images.productserve.com/thumb/513/51155349.jpg</sawthumburl>
        <fprice>18.35</fprice>
      </oproduct>
      <oproduct>
        <iid>187948</iid>
        <icategoryid>474</icategoryid>
        <imerchantid>496</imerchantid>
        <iadult>0</iadult>
        <sname>Rapitest Dm 10 Electrical Multimeter</sname>
        <sawdeeplink>http://www.awin1.com/pclick.php?p=187948&amp;a=111402&amp;m=496&amp;platform=cs</sawdeeplink>
        <sawthumburl>http://images.productserve.com/thumb/496/187948.jpg</sawthumburl>
        <fprice>26.71</fprice>
      </oproduct>
      <oproduct>
        <iid>51155353</iid>
        <icategoryid>428</icategoryid>
        <imerchantid>513</imerchantid>
        <iadult>0</iadult>
        <sname>Rapitest DM 10 Electrical Multimeter</sname>
        <sawdeeplink>http://www.awin1.com/pclick.php?p=51155353&amp;a=111402&amp;m=513&amp;platform=cs</sawdeeplink>
        <sawthumburl>http://images.productserve.com/thumb/513/51155353.jpg</sawthumburl>
        <fprice>22.7</fprice>
      </oproduct>
      <oproduct>
        <iid>49152850</iid>
        <icategoryid>474</icategoryid>
        <imerchantid>1366</imerchantid>
        <iadult>0</iadult>
        <sname>Testboy Profi LED Plus</sname>
        <sawdeeplink>http://www.awin1.com/pclick.php?p=49152850&amp;a=111402&amp;m=1366&amp;platform=cs</sawdeeplink>
        <sawthumburl>http://images.productserve.com/thumb/1366/49152850.jpg</sawthumburl>
        <fprice>44.99</fprice>
      </oproduct>
      <oproduct>
        <iid>51155350</iid>
        <icategoryid>428</icategoryid>
        <imerchantid>513</imerchantid>
        <iadult>0</iadult>
        <sname>Rapitest ETP 116 Electrical Test Probe</sname>
        <sawdeeplink>http://www.awin1.com/pclick.php?p=51155350&amp;a=111402&amp;m=513&amp;platform=cs</sawdeeplink>
        <sawthumburl>http://images.productserve.com/thumb/513/51155350.jpg</sawthumburl>
        <fprice>17.55</fprice>
      </oproduct>
      <oproduct>
        <iid>51155351</iid>
        <icategoryid>428</icategoryid>
        <imerchantid>513</imerchantid>
        <iadult>0</iadult>
        <sname>Rapitest ET 111 Electrical Test Meter</sname>
        <sawdeeplink>http://www.awin1.com/pclick.php?p=51155351&amp;a=111402&amp;m=513&amp;platform=cs</sawdeeplink>
        <sawthumburl>http://images.productserve.com/thumb/513/51155351.jpg</sawthumburl>
        <fprice>13.55</fprice>
      </oproduct>
      <oproduct>
        <iid>72326941</iid>
        <icategoryid>474</icategoryid>
        <imerchantid>496</imerchantid>
        <iadult>0</iadult>
        <sname>Rapitest Etp 116 Electrical Test Probe</sname>
        <sawdeeplink>http://www.awin1.com/pclick.php?p=72326941&amp;a=111402&amp;m=496&amp;platform=cs</sawdeeplink>
        <sawthumburl>http://images.productserve.com/thumb/496/72326941.jpg</sawthumburl>
        <fprice>20.66</fprice>
      </oproduct>
      <oproduct>
        <iid>49338340</iid>
        <icategoryid>206</icategoryid>
        <imerchantid>80</imerchantid>
        <iadult>0</iadult>
        <sname>Ladies Protest Zekke Jacket True Black</sname>
        <sawdeeplink>http://www.awin1.com/pclick.php?p=49338340&amp;a=111402&amp;m=80&amp;platform=cs</sawdeeplink>
        <sawthumburl>http://images.productserve.com/thumb/80/49338340.jpg</sawthumburl>
        <fprice>54.99</fprice>
      </oproduct>
      <itotalcount>6350</itotalcount>
    </ns1:getproductlistresponse>
  </soap-env:body>
</soap-env:envelope>

PHP附带了一个SOAP客户机,它可以使您不必手动解析SOAP XML。请看这里:


编辑:为了清楚起见,SOAP客户端不是PHP的一部分,而是一个扩展。

您能澄清一下您使用的是哪一个版本的PHP 4或5吗?您不想/不能使用PHP5的SOAP扩展还有什么特别的原因吗?了解这些信息将有助于我们为您提供更好的答案

上面的代码示例不起作用的原因是您在错误的名称空间中查找OpProduct节点。当根节点包含在SOAP命名空间中时,opproduct节点位于http://v3.core.com.productserve.com/ 命名空间。您还需要在XPath查询中使用名称空间别名。试试这个,尽管我还没有测试过:

$xml = simplexml_load_string($response);
$xml->registerXPathNamespace('ns', 'http://v3.core.com.productserve.com/');
foreach ($xml->xpath('//ns:oproduct') as $item)
{
  // do something
}
希望这能解决你眼前的问题

编辑 谢谢你的澄清。同样,未经测试,但这可能会起作用:

$xml = simplexml_load_string($response);
$xml->registerXPathNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('ns', 'http://v3.core.com.productserve.com/');
foreach ($xml->xpath('/soapenv:envelope/soapenv:body/ns:getproductlistresponse/ns:oproduct') as $item)
    {
      // do something
    }
也许您需要在查询中从根节点转到soap Env:body,再转到opproduct节点。希望这能奏效

进一步编辑: 我想我已经破解了这个。请尝试以下代码:

$xml = simplexml_load_string($response);
$ns = $xml->getNamespaces(true);
$soap = $xml->children($ns['soap-env']);
$getproductlistresponse = $soap->body->children($ns['ns1']);
foreach ($getproductlistresponse->children() as $item)
{
  //This example just accesses the iid node but the others are all available.
  echo (string) $item->iid . '<br />';
}

虽然不是最漂亮的代码,但它很有效。我希望能用XPath查询实现这一点,但这超出了我对XPath的基本知识。也许其他人可以使用XPath发布答案?

感谢Jeremy的回复。我正在使用PHP5。我这样做的原因是因为我需要使用multi_curl执行并行请求。我尝试了你的建议,但现在返回错误。嗨,乔,忘了我上次的编辑。我想我会打开一个代码编辑器并尝试一下,但我遇到的问题是我无法让simplexml\u load\u string解析响应字符串。它只返回一个空的SimpleXML对象。我会继续尝试,如果我得到答案,我会发回。谢谢你的帮助杰里米。我会试着把你上面添加的代码弄得乱七八糟,看看能不能让它正常工作。谢谢Jeremy。现在我有另一个问题。当响应被硬编码时,代码可以工作,但是当我尝试使用真正的soap响应时,它就不工作了。我得到的错误是:SimpleXMLElement::children[SimpleXMLElement.children]:节点不再存在。我找到了它。soap响应是从Firebug内部复制的,所有名称空间的大小写都是小写的。实际的soap响应有一些大写名称空间,这是导致问题的原因。无论如何,非常感谢杰里米的帮助。对不起,伙计们,我应该说得更清楚些。我这样做是因为我需要使用multi_curl,这样我就可以执行并行请求。有没有一种方法可以只使用soap客户端来解析soap响应?