使用PHP解析带有名称空间的SOAP XML响应

使用PHP解析带有名称空间的SOAP XML响应,php,xml,soap,namespaces,simplexml,Php,Xml,Soap,Namespaces,Simplexml,我有一个丑陋的XML,它上面有很多名称空间,当我尝试用simpleXML加载它时,如果我指出第一个名称空间,我会得到一个XML对象,但是使用其他名称空间的标记将无法到达该对象。 下面是SOAP响应 <?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="ht

我有一个丑陋的XML,它上面有很多名称空间,当我尝试用simpleXML加载它时,如果我指出第一个名称空间,我会得到一个XML对象,但是使用其他名称空间的标记将无法到达该对象。 下面是SOAP响应

<?xml version="1.0" encoding="utf-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns8502="http://tempuri.org">
   <SOAP-ENV:Header>
     <Interface PartnerID="FastBooking" PartnerType="Test" Version="1.0.0" />
     <Credentials HotelID="AC00006" User="User" Password="123456" />
     <Client Ref ="123456789" TimeStamp="2012-12-14T12:24:25+0100"/>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
     <ServiceNameRQ xmlns="urn:wsTest">
         <GetRatesRS>
             <Rates>
                 <Rate RateID="12984" FromDate="2010-05-12" ToDate="2010-06-30" RateType="PUBLIC" RateCode="RAC" MinRate="100" MaxRate="1000" Currency="EUR" ReadOnly="No" FromRateID="11456">
                    <RateName>Rack Rate</RateName>
                 </Rate>
                 <Rate RateID="13219" FromDate="2010-07-12" ToDate="2010-12-31" RateType="PUBLIC" RateCode="NORMAL" MinRate="100" MaxRate="1000" Currency="EUR" ReadOnly="Yes">
                    <RateName>Normal Rate</RateName>
                     <R1 Name="Single Occupancy" MinRate="90.00" MaxRate="1500.00" />
                     <R2 Name="Double Occupancy" MinRate="120.00" MaxRate="2000.00" />
                     <R3 Name="2 Nights" MinRate="150.00" MaxRate="2000.00" />
                    </Rate>
                     </Rates>
            </GetRatesRS>
        </ServiceNameRQ>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

但是我无法检索
SOAP-ENV:Body
GetRatesRS->Rates->Rate

可以像这样访问费率数据:

foreach($obj->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('urn:wsTest')->ServiceNameRQ->GetRatesRS->Rates->Rate as $rate)
{
    if(isset($rate->R1))
    {
       echo $rate->R1->attributes()->Name;
       echo $rate->R1->attributes()->MinRate;
    }
    if(isset($rate->R2))
    {
       echo $rate->R2->attributes()->Name;
       echo $rate->R2->attributes()->MinRate;
    }
}

$obj = simplexml_load_string($xml);

foreach($obj->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('urn:wsTest')->ServiceNameRQ->GetRatesRS->Rates->Rate as $rate)
{
    echo (string)$rate->RateName . "\n";
}
输出

机架速率
正常汇率

如果需要速率属性,可以这样获得它们(在循环中):

您可以像这样读取
R1
R2
元素:

foreach($obj->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('urn:wsTest')->ServiceNameRQ->GetRatesRS->Rates->Rate as $rate)
{
    if(isset($rate->R1))
    {
       echo $rate->R1->attributes()->Name;
       echo $rate->R1->attributes()->MinRate;
    }
    if(isset($rate->R2))
    {
       echo $rate->R2->attributes()->Name;
       echo $rate->R2->attributes()->MinRate;
    }
}

速率数据可以通过以下方式访问:

foreach($obj->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('urn:wsTest')->ServiceNameRQ->GetRatesRS->Rates->Rate as $rate)
{
    if(isset($rate->R1))
    {
       echo $rate->R1->attributes()->Name;
       echo $rate->R1->attributes()->MinRate;
    }
    if(isset($rate->R2))
    {
       echo $rate->R2->attributes()->Name;
       echo $rate->R2->attributes()->MinRate;
    }
}

$obj = simplexml_load_string($xml);

foreach($obj->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('urn:wsTest')->ServiceNameRQ->GetRatesRS->Rates->Rate as $rate)
{
    echo (string)$rate->RateName . "\n";
}
输出

机架速率
正常汇率

如果需要速率属性,可以这样获得它们(在循环中):

您可以像这样读取
R1
R2
元素:

foreach($obj->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('urn:wsTest')->ServiceNameRQ->GetRatesRS->Rates->Rate as $rate)
{
    if(isset($rate->R1))
    {
       echo $rate->R1->attributes()->Name;
       echo $rate->R1->attributes()->MinRate;
    }
    if(isset($rate->R2))
    {
       echo $rate->R2->attributes()->Name;
       echo $rate->R2->attributes()->MinRate;
    }
}

为什么要在XML响应上运行
stripslashes
?可能重复,这基本上是手动材料:,请参阅示例#2使用名称空间。为什么要在XML响应上运行
stripslashes
?可能重复,这基本上是手动材料:,参见示例#2使用名称空间。@Goldenkhattab有关如何读取R1和R2的信息,请参见我的编辑,只需对R3、R4等重复相同的操作即可etc@Goldenkhattab有关如何读取R1和R2,请参见我的编辑,只需重复R3、R4等的相同操作