使用SimpleXML和xpath解析Zimbra SOAP响应 [英] Parsing Zimbra SOAP response with SimpleXML and xpath

查看:132
本文介绍了使用SimpleXML和xpath解析Zimbra SOAP响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在使用PHP与Zimbra SOAP服务器通信.响应在<soap:Envelope>标记中.由于名称空间的原因,我在解析XML响应时遇到了麻烦.

So, I'm using PHP to talk to a Zimbra SOAP server. The response is in a <soap:Envelope> tag. I'm having trouble parsing the XML response because of the namespace(s).

XML看起来像这样:

The XML looks like this:

<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="iamtesting@example.com">
        <a n="zimbraId">83ebf344-dc51-47ae-9a36-3eb24281d53e</a>
        <a n="zimbraMailDeliveryAddress">iamtesting@example.com</a>
      </account>
    </CreateAccountResponse>
  </soap:Body>
</soap:Envelope>

我创建了一个新的SimpleXMLElement对象:

I make a new SimpleXMLElement object:

$xml = new SimpleXMLElement($data);

在谷歌搜索了一下之后,我发现我需要注册名称空间.所以我这样做:

After Googling a bit, I found I need to register the namespace. So I do that:

$xml->registerXPathNamespace('soap', 'http://www.w3.org/2003/05/soap-envelope');

然后我可以轻松获得<soap:Body>标签.

Then I can get the <soap:Body> tag easily.

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

但是之后(使用xpath),我什么也没得到:

But I can't get any elements after that (using xpath):

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

这将返回一个空数组.不过,我可以遍历XML,以获取该元素.

This returns an empty array. I can traverse the XML though, to get that element.

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

这很好用,但是现在我想获得<a>标记,特别是zimbraId标记.所以我尝试了这个:

This works fine, but now I want to get the <a> tags, specifically the zimbraId one. So I tried this:

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

不走运,我得到一个空白数组.这是怎么回事?为什么我不能使用xpath来获取元素(不是以soap:开头的元素)?

No luck, I get a blank array. What's going on? Why can't I use xpath to get elements (that don't start with soap:)?

如何根据n属性获取<a>标签?

How can I get the <a> tags based on their n attribute?

P.S.我知道idname也在<account>标记的属性中,但是我想使用n属性获得更多的<a>标记.

P.S. I'm aware that the id and name are also in the <account> tag's attributes, but there are a bunch more <a> tags that I want to get using the n attribute.

注意:我正在尝试为我的工作应用程序改进Zimbra库.当前获取<a>标签的代码如下:

Note: I'm trying to improve the Zimbra library for my application for work. The current code to get the <a> tags is as follows:

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

很明显,我想删除此代码(代码中稍后还会有一些正则表达式( shudder )),并使用XML解析器.

Obviously, I want to remove this code (there's also some regexes (shudder) later on in the code), and use an XML parser.

推荐答案

要检索的元素也具有名称空间,即urn:zimbraAdmin.

The elements you want to retrieve have a namespace as well, namely urn:zimbraAdmin.

    <CreateAccountResponse xmlns="urn:zimbraAdmin">

xmlns属性指出所有子元素的默认名称空间,因此即使没有使用前缀,您尝试检索的元素实际上也具有名称空间(请参见

The xmlns attribute states the default namespace for any child elements, so the elements you are trying to retrieve actually have a namespace, even though no prefix is used (see the wikipedia article for some examples). If you specify a namespace prefix as you did for http://www.w3.org/2003/05/soap-envelope you should be fine.

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

这篇关于使用SimpleXML和xpath解析Zimbra SOAP响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆