这是xml :( a.xml )
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ser="http://www.example.com/v1/services">
<soapenv:Header/>
<soapenv:Body>
<ser:getAnalyticalDeliveryEstimatesRequest>
<ser:buyer>
<ser:buyerId>1233</ser:buyerId>
<ser:toCountry>IN</ser:toCountry>
<ser:toZip>110001</ser:toZip>
</ser:buyer>
<ser:item>
<ser:id>25164</ser:id>
<ser:categoryId>15032</ser:categoryId>
<ser:seller>
<ser:sellerId>11997</ser:sellerId>
<ser:fromCountry>IN</ser:fromCountry>
</ser:seller>
<ser:transactionId>0</ser:transactionId>
</ser:item>
</ser:getAnalyticalDeliveryEstimatesRequest>
</soapenv:Body>
</soapenv:Envelope>
用于解析此问题的PHP代码:
$xml = simplexml_load_file( 'a.xml', NULL, NULL, 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('soapenv', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('ser', 'http://www.example.com/v1/services');
$xpath = $xml->xpath( '//soapenv:Body/ser:getAnalyticalDeliveryEstimatesRequest' );
print_r($xpath);
它没有提供数据。
如果我做错了,请告诉我。
答案 0 :(得分:2)
首先,在您的示例代码中,您实际上并未在任何地方定义$node
:
$xpath = $xml->xpath( '//soapenv:Body/ser:getAnalyticalDeliveryEstimatesRequest' );
print_r($node);
应该是:
$xpath = $xml->xpath( '//soapenv:Body/ser:getAnalyticalDeliveryEstimatesRequest' );
$node = $xpath[0];
print_r($node);
或者也许:
$xpath = $xml->xpath( '//soapenv:Body/ser:getAnalyticalDeliveryEstimatesRequest' );
foreach ( $xpath as $node ) {
print_r($node);
}
其次,print_r
在显示SimpleXML对象方面并不出色。它给你一个空输出并不意味着该元素是空的。
例如,尝试回显找到的节点的名称(Demo):
$xpath = $xml->xpath( '//soapenv:Body/ser:getAnalyticalDeliveryEstimatesRequest' );
foreach ( $xpath as $node ) {
echo $node->getName();
}
要获取其内容,您需要使用the ->children()
method选择它们所在的命名空间,此时即使print_r
也能看到它们(尽管有其他原因不能依赖它们)完全)(Demo):
$xpath = $xml->xpath( '//soapenv:Body/ser:getAnalyticalDeliveryEstimatesRequest' );
foreach ( $xpath as $node ) {
print_r( $node->children('http://www.example.com/v1/services') );
}
尝试搜索“带名称空间的SimpleXML”以获取更多示例。
答案 1 :(得分:1)
看到那些不起作用很奇怪,但也可以使用它:
$dom = new DOMDocument();
$dom->loadXML($xml);
$xpath = new DOMXpath($dom);
$element = $xpath->query('//soapenv:Body/ser:getAnalyticalDeliveryEstimatesRequest');
foreach($element->item(0)->childNodes as $node) {
// perform your actions here
}
编辑:这也是另一种方式:
$xml_string ='<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ser="http://www.example.com/v1/services">
<soapenv:Header/>
<soapenv:Body>
<ser:getAnalyticalDeliveryEstimatesRequest>
<ser:buyer>
<ser:buyerId>1233</ser:buyerId>
<ser:toCountry>IN</ser:toCountry>
<ser:toZip>110001</ser:toZip>
</ser:buyer>
<ser:item>
<ser:id>25164</ser:id>
<ser:categoryId>15032</ser:categoryId>
<ser:seller>
<ser:sellerId>11997</ser:sellerId>
<ser:fromCountry>IN</ser:fromCountry>
</ser:seller>
<ser:transactionId>0</ser:transactionId>
</ser:item>
</ser:getAnalyticalDeliveryEstimatesRequest>
</soapenv:Body>
</soapenv:Envelope>';
$xml = simplexml_load_string($xml_string, null, null, 'http://schemas.xmlsoap.org/soap/envelope/');
$ns = $xml->getNamespaces(true);
$soap = $xml->children($ns['soapenv']);
foreach($soap->Body as $nodes) {
$ser = $nodes->children($ns['ser'])->getAnalyticalDeliveryEstimatesRequest;
foreach($ser->buyer as $sub_nodes) { // this can also be ->item as well
}
}