[英]can't figure out SimpleXML syntax
我正在尝试从肥皂请求XML的日志中解析某些项目,似乎无法弄清楚如何进入SimpleXMLElement的内部。 这是我使用的XML的示例:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://fedex.com/ws/rate/v9">
<SOAP-ENV:Body>
<ns1:RateRequest>
<ns1:WebAuthenticationDetail>
<ns1:UserCredential>
<ns1:Key>aaaaaaaaaaa</ns1:Key>
<ns1:Password>aaaaaaaaaaaaaaaaaaa</ns1:Password>
</ns1:UserCredential>
</ns1:WebAuthenticationDetail>
<ns1:ClientDetail>
<ns1:AccountNumber>11111111</ns1:AccountNumber>
<ns1:MeterNumber>88888888</ns1:MeterNumber>
</ns1:ClientDetail>
<ns1:TransactionDetail>
<ns1:CustomerTransactionId>1</ns1:CustomerTransactionId>
</ns1:TransactionDetail>
<ns1:Version>
<ns1:ServiceId>crs</ns1:ServiceId>
<ns1:Major>9</ns1:Major>
<ns1:Intermediate>0</ns1:Intermediate>
<ns1:Minor>0</ns1:Minor>
</ns1:Version>
<ns1:ReturnTransitAndCommit>true</ns1:ReturnTransitAndCommit>
<ns1:RequestedShipment>
<ns1:ShipTimestamp>2013-08-06T12:39:26-04:00</ns1:ShipTimestamp>
<ns1:DropoffType>REGULAR_PICKUP</ns1:DropoffType>
<ns1:Shipper>
<ns1:AccountNumber>11111111</ns1:AccountNumber>
<ns1:Address>
<ns1:StreetLines>24 Seaview Blvd</ns1:StreetLines>
<ns1:City>Port Washington</ns1:City>
<ns1:StateOrProvinceCode>NY</ns1:StateOrProvinceCode>
<ns1:PostalCode>11050</ns1:PostalCode>
<ns1:CountryCode>US</ns1:CountryCode>
</ns1:Address>
</ns1:Shipper>
<ns1:Recipient>
<ns1:Address>
<ns1:StreetLines>1234 Fifth Street</ns1:StreetLines>
<ns1:City>Sixton</ns1:City>
<ns1:StateOrProvinceCode>AR</ns1:StateOrProvinceCode>
<ns1:PostalCode>72712</ns1:PostalCode>
<ns1:CountryCode>US</ns1:CountryCode>
</ns1:Address>
</ns1:Recipient>
<ns1:ShippingChargesPayment>
<ns1:Payor>
<ns1:AccountNumber>11111111</ns1:AccountNumber>
<ns1:CountryCode>US</ns1:CountryCode>
</ns1:Payor>
</ns1:ShippingChargesPayment>
<ns1:RateRequestTypes>ACCOUNT</ns1:RateRequestTypes>
<ns1:PackageCount>1</ns1:PackageCount>
<ns1:PackageDetail>INDIVIDUAL_PACKAGES</ns1:PackageDetail>
<ns1:RequestedPackageLineItems>
<ns1:Weight>
<ns1:Units>LB</ns1:Units>
<ns1:Value>14</ns1:Value>
</ns1:Weight>
<ns1:Dimensions>
<ns1:Length>20</ns1:Length>
<ns1:Width>20</ns1:Width>
<ns1:Height>9</ns1:Height>
<ns1:Units>IN</ns1:Units>
</ns1:Dimensions>
</ns1:RequestedPackageLineItems>
</ns1:RequestedShipment>
</ns1:RateRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我正在尝试获取诸如CountryCode,PostalCode Weight-> Value之类的值以及所有维度,但是名称空间使我感到困惑。 每当我解析它,并在调试器中查看时,对于任何给定变量,我所看到的都是{SimpleXMLElement} [0],但有些仍将显示-> asXML()的输出,但是我大多数尝试访问数据的尝试都会出错,返回false ,或返回另一个{SimpleXMLElement} [0]。 我只想要这些节点的字符串/值!
例如,以下内容完全不输出:
$fReq = simplexml_load_string($xmlRequest);
$fReq->registerXPathNamespace('ns1', 'http://fedex.com/ws/rate/v9');
$ns = $fReq->getNameSpaces(true);
$rr = $fReq->children($ns['ns1']);
echo $rr->asXML()."\n";
我更喜欢使用XMLReader: http : //us3.php.net/manual/en/class.xmlreader.php
这是一个PHP表单示例,并进行了少量修改以满足您的要求:
function xmlParse($content,$wrapperName,$callback,$limit=NULL){
$xml = new XMLReader();
$xml->xml($content);
$n=0;
$x=0;
while($xml->read()){
if($xml->nodeType==XMLReader::ELEMENT && $xml->name == $wrapperName){
while($xml->read() && $xml->name != $wrapperName){
if($xml->nodeType==XMLReader::ELEMENT){
$name = $xml->name;
$xml->read();
$value = $xml->value;
if(preg_match("/[^\s]/",$value)){
$subarray[$name] = $value;
}
}
}
if($limit==NULL || $x<$limit){
if($callback($subarray)){
$x++;
}
unset($subarray);
}
$n++;
}
}
$xml->close();
}
xmlParse($test,'SOAP-ENV:Envelope','callback');
function callback($array){
var_dump($array);
}
只需对您的XML执行此操作即可返回
Array
(
[ns1:Key] => aaaaaaaaaaa
[ns1:Password] => aaaaaaaaaaaaaaaaaaa
[ns1:AccountNumber] => 11111111
[ns1:MeterNumber] => 88888888
[ns1:CustomerTransactionId] => 1
[ns1:ServiceId] => crs
[ns1:Major] => 9
[ns1:Intermediate] => 0
[ns1:Minor] => 0
[ns1:ReturnTransitAndCommit] => true
[ns1:ShipTimestamp] => 2013-08-06T12:39:26-04:00
[ns1:DropoffType] => REGULAR_PICKUP
[ns1:StreetLines] => 1234 Fifth Street
[ns1:City] => Sixton
[ns1:StateOrProvinceCode] => AR
[ns1:PostalCode] => 72712
[ns1:CountryCode] => US
[ns1:RateRequestTypes] => ACCOUNT
[ns1:PackageCount] => 1
[ns1:PackageDetail] => INDIVIDUAL_PACKAGES
[ns1:Units] => IN
[ns1:Value] => 14
[ns1:Length] => 20
[ns1:Width] => 20
[ns1:Height] => 9
)
问候
除非使用XPath,否则无需调用registerXPathNamespace
。 但是,您确实需要遍历SOAP Body
元素,这意味着您需要考虑两个名称空间,而不仅仅是一个。
也不希望像ns1
这样的名称空间前缀在将来保持不变。 保证的部分是xmlns
属性中的实际URI。 使其更具可读性的一种方法是为应用程序中使用的XML名称空间定义常量,并在必要时将其传递给->children()
和->attributes()
方法。
还要注意->children()
“选择”一个命名空间,直到另行通知,因此,一旦选择了Fedex命名空间并遍历到RateRequest
节点,就可以访问元素,就好像命名空间不是问题一样(因为下面的所有内容)该文档位于同一名称空间中)。
这是一个完整的示例,显示了它的外观( 请参见此处的实时演示 )。
// Give your own aliases to namespaces, don't rely on the XML always having the same ones
define('NS_SOAP', 'http://schemas.xmlsoap.org/soap/envelope/');
define('NS_FEDEX_RATE', 'http://fedex.com/ws/rate/v9');
// Parse the XML
$sx = simplexml_load_string($xml_string);
// $sx now represents the <SOAP-ENV:Envelope> element
// Traverse through the SOAP Body
$sx_soap_body = $sx->children(NS_SOAP)->Body;
// Now "switch" to the Fedex namespace, and start with the RateRequest node
$sx_rate_request = $sx_soap_body->children(NS_FEDEX_RATE)->RateRequest;
// Now traverse as normal, e.g. to the Recipient's CountryCode
// (the string cast isn't necessary for echo, but is a good habit to get into)
echo (string)$sx_rate_request->RequestedShipment->Recipient->Address->CountryCode;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.