1

我有以下 XML(你可以说 SOAP 请求):

<SOAPENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:NS="http://xyz.gov/headerschema" >
    <SOAPENV:Header>
        <NS:myHeader>
            <NS:SourceID>223423</NS:SourceID>
        </NS:myHeader>
    </SOAPENV:Header>
</SOAPENV:Envelope>

我使用以下代码,它工作正常:

<?php 
$myRequest ='<SOAPENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:NS="http://xyz.gov/headerschema" >
   <SOAPENV:Header>
      <NS:myHeader>
         <NS:SourceID>223423</NS:SourceID>
      </NS:myHeader>
   </SOAPENV:Header>
   </SOAPENV:Envelope>';
$xml = simplexml_load_string($myRequest, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");
$namespaces = $xml->getNameSpaces(true);

$soapHeader = $xml->children($namespaces['SOAPENV'])->Header;
$myHeader = $soapHeader->children($namespaces['NS'])->myHeader;
echo (string)$myHeader->SourceID;
?>

问题

我知道前缀( SOAPENV + NS ),但客户端可以将前缀更改为他们想要的任何前缀,因此他们可能会向我发送具有( MY-SOAPENV + MY-NS)前缀的 xml 文档。

我的问题

由于命名空间前缀不是静态的,我该如何处理,我该如何解析它?

谢谢

4

2 回答 2

5

这是另一种方式。我们可以如下动态解析数据。

$myRequest ='<SOAPENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:NS="http://xyz.gov/headerschema" >
           <SOAPENV:Header>
              <NS:myHeader>
                 <NS:SourceID>223423</NS:SourceID>
              </NS:myHeader>
           </SOAPENV:Header>
           </SOAPENV:Envelope>';


$xml        = simplexml_load_string(
    $myRequest, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/"
);
$namespaces = $xml->getNameSpaces(true);
$prefix     = array_keys($namespaces); // we getting all namespaces here. According 
                                       // to that we can find datas.
$soapHeader = $xml->children($namespaces[$prefix[0]])->Header;
$myHeader   = $soapHeader->children($namespaces[$prefix[1]])->myHeader;
echo (string)$myHeader->SourceID;
于 2013-06-26T11:49:36.033 回答
3

您应该使用DOM- 我个人认为这适用于一般情况,因为“简单 XML”是矛盾的,但我知道其他人不同意。在处理像 SOAP 这样的复杂文档树时确实如此。

DOM 提供getElementsByTagNameNS()(和其他相关的 NS 定位方法)允许您指定名称空间URI(即应该保持静态并提前知道的东西)而不是特定于前缀。

$soapNsUri = 'http://schemas.xmlsoap.org/soap/envelope/';
$myNsUri = 'http://xyz.gov/headerschema';

$doc = new DOMDocument;
$doc->loadXML($myRequest);

$header = $doc->getElementsByTagNameNS($soapNsUri, 'Header')->item(0);
$myHeader = $header->getElementsByTagNameNS($myNsUri, 'myHeader')->item(0);
$sourceID = $myHeader->getElementsByTagNameNS($myNsUri, 'SourceID')->item(0);

echo $sourceID->firstChild->data;

看到它工作

于 2013-06-26T10:18:45.947 回答