Xml 从SOAPClient响应解析命名空间
好的,我让SOAPClient打电话。如果我使用uu getLastResponse(),我会在XML中得到一行,如下所示:Xml 从SOAPClient响应解析命名空间,xml,soap,xml-namespaces,soap-client,Xml,Soap,Xml Namespaces,Soap Client,好的,我让SOAPClient打电话。如果我使用uu getLastResponse(),我会在XML中得到一行,如下所示: <Discount xsi:type="ProgressivePromotion" from="2013-05-05T00:00:00" to="2013-05-14T00:00:00" type="Percent" value="20" name="Special Deal"/> 使用返回的对象时,我可以从折扣元素访问以下属性: 类型:渐进式促销 起始日期
<Discount xsi:type="ProgressivePromotion" from="2013-05-05T00:00:00" to="2013-05-14T00:00:00" type="Percent" value="20" name="Special Deal"/>
使用返回的对象时,我可以从折扣元素访问以下属性:
类型:渐进式促销起始日期:2013-05-05T00:00:00
致:2013-05-14T00:00:00
值:20
名称:特价 但我无法访问type=“Percent” SOAPClient似乎忽略了xsi:type中的xsi名称空间,而只是将该属性存储为type 那么,我如何访问xsi:type和type,以便判断我的折扣是百分比、金额还是其他类型的折扣呢 顺便说一句,在SOAP响应的顶部,我没有看到任何声明xsi是什么的内容
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<SearchHotelsResponse xmlns="http://tourico.com/webservices/hotelv3">
<SearchHotelsResult>
<Info xmlns="http://schemas.tourico.com/webservices/hotelv3" version="9.71" culture="en-US" serverTime="2013-02-06T14:49:58.3500117-05:00"/>
<HotelList xmlns="http://schemas.tourico.com/webservices/hotelv3">
查看我如何丢失type=“Amount”
我不能这样叫折扣
echo $result->SearchHotelsResult->HotelList->Hotel[0]->RoomTypes->RoomType[0]->Discounts->type;
因为我得到
Undefined property: stdClass::$Discounts Notice: Trying to get property of non-object
因此,我将整个对象转换为一个巨大的多维数组,并以这种方式访问对象。无论如何,type=“Amount”不会被提取。我这样解决了问题
<?php
class fixSoapClient extends SoapClient{
function __doRequest($request, $location, $action, $version, $one_way = 0) {
$result = parent::__doRequest($request, $location, $action, $version);
$str = preg_replace('#<Discount xsi:type="ProgressivePromotion"(.+)type="(.+)"(.+)name="(.+)"/>#isU',
'<Discount xsi:type="ProgressivePromotion"$1type="wath ever"$3name="$2"/>', $result);
return $str;
}
}
似乎您正在使用一个名称空间感知的XML解析器解析您的响应,但是该解析器的名称空间支持没有打开。这会导致两条规则发生冲突
当使用名称空间解析XML文档时,所有元素和属性都会使用其扩展名称引用。扩展名称由名称空间URI和元素/属性的本地名称组成。如果解析器不知道名称空间,则名称的URI部分将丢失。因此,如果未启用名称空间支持,一些具有名称空间支持的解析器也会删除名称空间前缀
元素不允许包含具有相同(扩展)名称的两个属性。在这种情况下,另一个属性将丢失。通常,支持名称空间的XML解析器会将这两个type
属性视为{http://www.w3.org/2001/XMLSchema-instance}键入
和键入
(使用詹姆斯·克拉克符号)。非名称空间感知解析器应该返回属性名xsi:type
和type
。在这些情况下,没有名称冲突,一切正常
如果解析器知道冒号:
用作名称空间前缀分隔符,但解析器未使用名称空间,因此会删除分隔符和名称空间前缀,则会出现问题。然后,这两个属性都将获得nametype
,其中一个属性由于属性名称唯一性规则而丢失/覆盖
解决方案:为您的解析器设置名称空间支持,或者切换到另一个功能更强大的解析器。如果您使用有关XML文件解析方式的信息更新您的问题,希望有人能给出更具体的答案。xsi
就在第二行声明:xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“
。您能提供访问这些属性所使用的代码吗?这是一个命名空间问题,客户端对“”一无所知,认为有两个“类型”属性,并使用最后一个。您是否向您的客户机提供了wsdl?如果不是,那么应该在构造函数的参数数组中显式指定名称空间。您的示例将name=替换为ProgressivePromotion,而不是实际名称(“特价”),为了使这更复杂,还可能添加了其他属性,例如pay=和stay=No,xsi:type始终是“ProgressivePromotion”(它是ComplexType)。如果您还需要name属性,那么,例如,您可以保留name属性值+'#',然后保留折扣类型值,如name=“Special Deal#Percent”,然后按#分割(并且name和type都有),您不能添加额外的属性,因为内部解析器将使用xsd检查xml(由于xsd没有定义额外的属性,它们将无法识别).但我认为你有这个想法,-这是可行的,也是可以接受的,但我想看看是否有人可以在我提供赏金之前分享如何获取实际属性。这个问题可以帮助很多处理名称空间问题的人。这是内部解析器中的一个bug,提供的解决方案并不是很糟糕(这是一个破解,但很好)。解决此问题的唯一其他选项是使用第三方SoapCient。XML文件是如何解析的?我不明白。我正在使用上述SOAPClient。还有其他方法吗?
Undefined property: stdClass::$Discounts Notice: Trying to get property of non-object
<?php
class fixSoapClient extends SoapClient{
function __doRequest($request, $location, $action, $version, $one_way = 0) {
$result = parent::__doRequest($request, $location, $action, $version);
$str = preg_replace('#<Discount xsi:type="ProgressivePromotion"(.+)type="(.+)"(.+)name="(.+)"/>#isU',
'<Discount xsi:type="ProgressivePromotion"$1type="wath ever"$3name="$2"/>', $result);
return $str;
}
}