2012-04-25 14 views
0

私はZimbra SOAPサーバーと話すためにPHPを使用しています。応答は<soap:Envelope>タグ内にあります。私は名前空間のためにXML応答の解析に問題があります。SimpleXMLとxpathによるZimbra SOAP応答の解析

XMLは次のようになります。

$xml = new SimpleXMLElement($data); 

ビットをグーグルでの後、私は名前空間を登録する必要が見つかりました

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> 
    <soap:Header> 
    <context xmlns="urn:zimbra"> 
     <change token="20333"/> 
    </context> 
    </soap:Header> 
    <soap:Body> 
    <CreateAccountResponse xmlns="urn:zimbraAdmin"> 
     <account id="83ebf344-dc51-47ae-9a36-3eb24281d53e" name="[email protected]"> 
     <a n="zimbraId">83ebf344-dc51-47ae-9a36-3eb24281d53e</a> 
     <a n="zimbraMailDeliveryAddress">[email protected]</a> 
     </account> 
    </CreateAccountResponse> 
    </soap:Body> 
</soap:Envelope> 

は、私は新しい SimpleXMLElementオブジェクトを作ります。だから私はそれを行う:

私は簡単に<soap:Body>タグを得ることができます。

$body = $xml->xpath('//soap:Body'); 

しかし、私は(XPathを使用して)、その後の任意の要素を取得することはできません。

$CreateAccountResponse = $xml->xpath('//soap:Body/CreateAccountResponse'); 

これは空の配列を返します。私はその要素を得るために、XMLをトラバースすることができます。

$CreateAccountResponse = $body[0]->CreateAccountResponse; 

これは正常に動作しますが、今私は、具体的 1、<a>タグを取得したいです。だから私はこれを試した:

$zimbraId = $CreateAccountResponse->account->xpath('a[@n=zimbraId]'); 

私は空の配列を取得します。どうしたの? xpathを使用して要素を取得できないのはなぜですか(soap:で始まらない)?

n属性に基づいて<a>タグを取得するにはどうすればよいですか?

P.S. idname<account>タグの属性にも含まれていますが、n属性を使用して取得したいと思っているタグがさらに多い<a>タグがあります。

注:私は仕事のために私のアプリケーションのZimbraライブラリを改善しようとしています。次のように<a>タグを取得するには、現在のコードは次のとおりです。

$zimbraId = strstr($data, "<a n=\"zimbraId\""); 
$zimbraId = strstr($zimbraId, ">"); 
$zimbraId = substr($zimbraId, 1, strpos($zimbraId, "<") - 1); 

もちろん、私は(後にコードでのいくつかの正規表現(身震い)もあります)、このコードを削除し、XMLパーサーを使用します。

答えて

4

取得する要素には、名前空間もあります。つまり、urn:zimbraAdminです。

<CreateAccountResponse xmlns="urn:zimbraAdmin"> 

xmlns属性は、どの子要素のデフォルトの名前空間を述べ、あなたが取得しようとしている要素は、実際には(いくつかの例についてthe wikipedia articleを参照)は、接頭辞が使用されていないにも関わらず、名前空間を持っています。 http://www.w3.org/2003/05/soap-envelopeのように名前空間の接頭辞を指定すると、うまくいくはずです。

$xml->registerXPathNamespace('soap', 'http://www.w3.org/2003/05/soap-envelope'); 
$xml->registerXPathNamespace('zimbra', 'urn:zimbraAdmin'); 
$CreateAccountResponse = $xml->xpath('//soap:Body/zimbra:CreateAccountResponse'); 
+0

ありがとう、ありがとう。それがトリックでした。一旦私が 'zimbra'名前空間を登録すると、それはすべて機能しました(すべてに' zimbra: 'で接頭辞が付けられている限り)。私はこのxpathクエリを使用して、必要な要素を取得します: '' // soap:Body/zimbra:CreateAccountResponse/zimbra:account/zimbra:a [@ n = "zimbraId"] '' –

+0

変数に保存した場合、要素に対して 'registerXPathNamespace'を実行しなければならないこともわかりました。 '$ x = $ CreateAccountResponse [0] - > account;' $ x-> registerXPathNamespace( 'zimbra'、 'urn:zimbraAdmin'); 'を実行して動作させる必要がありました。そして、私は '$ x-> xpath( 'zimbra:a [@ n =" zimbraId "]')'を実行できます。 –

+1

この投稿は残念ながらその事実を協力しているようです:http://www.qc4blog.com/?p=443 – erikxiv