正在检索域中所有 Google 日历资源中的 XML?
Retrieving XML of all Google Calendar Resources on a domain?
我目前正在 PHP 中处理一个表格,该表格将合并两项不同的任务:为活动预订 space,以及为在线日历注册活动。我用 PHP 的 API 客户端确定了 Google 日历片段,但 Calendar Resources 仍然是个问题。
以下是关于我目前所在位置的一些信息:
- I am using the general API to handle the OAuth2 authorization on the Calendar and Resource scopes.
- Resource Scope: https://apps-apis.google.com/a/feeds/calendar/resource/
- I use the access token to make a cURL GET request to the Resource feed in an attempt to retrieve the XML data on all of the available
resources.
- Resource Call: https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/
- Assuming the above worked, I would use the resource emails pulled from the XML to invite selected resources to the event made with the Calendar API.
我目前的困境涉及我从通话中 return 收集的数据。当我使用 Google OAuth2 Playground 通过上述 URI 发出请求时,它会毫无问题地检索 XML 数据。当我在 PHP 中进行相同的尝试时,我得到了具有以下格式的单个字符串中的数据:
- https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/5798411496212015-02-12T18:42:23.268Z
- "request_uri"."resource_id"."date_of_access" (x 100)
我知道每次请求只会return每次请求100个资源,而且游乐场和我的phpreturn好像都是100个条目,所以没有出现必然是授权问题。话虽这么说,但我不确定我在操场上的做法会有所不同。
我的 cURL 请求如下(一旦检索到 access_token):
$url = 'https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/';
$token = json_decode($_SESSION['access_token'], true);
$access_token = $token['access_token'];
$token_type = $token['token_type'];
//open connection
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => array('Authorization: '.$token_type.' '.$access_token,),
));
// $output contains the returned data
$output = curl_exec($ch);
if($output === false) { echo 'Curl error: ' . curl_error($ch); }
else { echo $output; }
// close curl resource to free up system resources
curl_close($ch);
是否有我遗漏的 cURL 设置或 header?我猜不出它会是什么,尤其是当 Playground 的请求如下时:
GET /a/feeds/calendar/resource/2.0/domain/ HTTP/1.1
Host: apps-apis.google.com
Content-length: 0
Authorization: Bearer access_token
更新
Hans Z. 的回答促使我(谢谢!)寻找将 XML 数据放入数组的方法,因为我需要使用获得的数据而不是显示它。 (我很抱歉最初没有说清楚。)There are a lot of posts on the subject,在通过 SimpleXML 输出后,我检索了以下内容作为每个资源 (x100) 的条目:
[0] => SimpleXMLElement Object
(
[id] => https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621
[updated] => 2015-02-18T17:04:16.481Z
[link] => Array
(
[0] => SimpleXMLElement Object
(
[@attributes] => Array
(
[rel] => self
[type] => application/atom+xml
[href] => https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621
)
)
[1] => SimpleXMLElement Object
(
[@attributes] => Array
(
[rel] => edit
[type] => header('Content-type: application/xml');
[href] => https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621
)
)
)
)
如上所示,这不会提供有关资源本身的任何信息,例如名称或电子邮件(或 ID,以任何直接 parse-less 方式)。我通过 SimpleXML 尝试了 运行 playground 的 XML 输出,并且正在恢复完全相同的输出。假设它与 SimpleXML 相关,我进行了更多搜索并找到了 this question, this question, and this blog post。我本人一直在研究他们的建议,但迄今为止收效甚微。如果有人想在我之前解决这个问题(因为我今天剩下的大部分时间都必须参加会议),这里有一个 XML 结构的例子:
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:apps='http://schemas.google.com/apps/2006'>
<id>https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain</id>
<updated>2015-02-18T17:03:03.057Z</updated>
<link rel='next' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/?start=579841149621'/>
<link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain'/>
<link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain'/>
<link rel='self' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain'/>
<openSearch:startIndex>1</openSearch:startIndex>
<entry>
<id>https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621</id>
<updated>2015-02-18T17:03:03.056Z</updated>
<link rel='self' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621'/>
<link rel='edit' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621'/>
<apps:property name='resourceId' value='579841149621'/>
<apps:property name='resourceCommonName' value='Projector'/>
<apps:property name='resourceEmail' value='domain_key@resource.calendar.google.com'/>
</entry>
//99 more times:
<entry>
...
</entry>
您的脚本运行良好,但您正在浏览器中查看脚本的输出。浏览器将尝试将 XML 输出解析为 HTML,从而得出观察到的结果。更改您的代码,使其向浏览器指示响应为 XML,如下所示:
header('Content-type: application/xml');
if($output === false) { echo 'Curl error: ' . curl_error($ch); }
else { echo $output; }
或者使用命令行 PHP 解释器查看输出。
编辑:
您可能更乐意在 PHP 中解析 JSON;您可以通过将 alt=json
添加到请求中来获得 JSON 中的结果,如:
https://apps-apis.google.com/a/feeds/calendar/resource/2.0/<domain>/?alt=json
并将 $output = json_decode($output)
应用于输出;然后您可以访问所需的数据,例如第一个资源的邮箱地址,如下:
$output->feed->entry[0]->{'apps$property'}[2]->value
以下是 Hans Z. 为那些宁愿将资源作为数组处理的人提供的替代解决方案:
$array = json_decode($output, true);
$resources = $array['feed']['entry'];
foreach ($resources as $resource) {
$id = $resource['apps$property']['0']['value'];
$name = $resource['apps$property']['1']['value'];
$email = $resource['apps$property']['2']['value'];
//do something with data
}
我目前正在 PHP 中处理一个表格,该表格将合并两项不同的任务:为活动预订 space,以及为在线日历注册活动。我用 PHP 的 API 客户端确定了 Google 日历片段,但 Calendar Resources 仍然是个问题。
以下是关于我目前所在位置的一些信息:
- I am using the general API to handle the OAuth2 authorization on the Calendar and Resource scopes.
- Resource Scope: https://apps-apis.google.com/a/feeds/calendar/resource/
- I use the access token to make a cURL GET request to the Resource feed in an attempt to retrieve the XML data on all of the available resources.
- Resource Call: https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/
- Assuming the above worked, I would use the resource emails pulled from the XML to invite selected resources to the event made with the Calendar API.
我目前的困境涉及我从通话中 return 收集的数据。当我使用 Google OAuth2 Playground 通过上述 URI 发出请求时,它会毫无问题地检索 XML 数据。当我在 PHP 中进行相同的尝试时,我得到了具有以下格式的单个字符串中的数据:
- https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/5798411496212015-02-12T18:42:23.268Z
- "request_uri"."resource_id"."date_of_access" (x 100)
我知道每次请求只会return每次请求100个资源,而且游乐场和我的phpreturn好像都是100个条目,所以没有出现必然是授权问题。话虽这么说,但我不确定我在操场上的做法会有所不同。
我的 cURL 请求如下(一旦检索到 access_token):
$url = 'https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/';
$token = json_decode($_SESSION['access_token'], true);
$access_token = $token['access_token'];
$token_type = $token['token_type'];
//open connection
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => array('Authorization: '.$token_type.' '.$access_token,),
));
// $output contains the returned data
$output = curl_exec($ch);
if($output === false) { echo 'Curl error: ' . curl_error($ch); }
else { echo $output; }
// close curl resource to free up system resources
curl_close($ch);
是否有我遗漏的 cURL 设置或 header?我猜不出它会是什么,尤其是当 Playground 的请求如下时:
GET /a/feeds/calendar/resource/2.0/domain/ HTTP/1.1
Host: apps-apis.google.com
Content-length: 0
Authorization: Bearer access_token
更新
Hans Z. 的回答促使我(谢谢!)寻找将 XML 数据放入数组的方法,因为我需要使用获得的数据而不是显示它。 (我很抱歉最初没有说清楚。)There are a lot of posts on the subject,在通过 SimpleXML 输出后,我检索了以下内容作为每个资源 (x100) 的条目:
[0] => SimpleXMLElement Object
(
[id] => https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621
[updated] => 2015-02-18T17:04:16.481Z
[link] => Array
(
[0] => SimpleXMLElement Object
(
[@attributes] => Array
(
[rel] => self
[type] => application/atom+xml
[href] => https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621
)
)
[1] => SimpleXMLElement Object
(
[@attributes] => Array
(
[rel] => edit
[type] => header('Content-type: application/xml');
[href] => https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621
)
)
)
)
如上所示,这不会提供有关资源本身的任何信息,例如名称或电子邮件(或 ID,以任何直接 parse-less 方式)。我通过 SimpleXML 尝试了 运行 playground 的 XML 输出,并且正在恢复完全相同的输出。假设它与 SimpleXML 相关,我进行了更多搜索并找到了 this question, this question, and this blog post。我本人一直在研究他们的建议,但迄今为止收效甚微。如果有人想在我之前解决这个问题(因为我今天剩下的大部分时间都必须参加会议),这里有一个 XML 结构的例子:
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:apps='http://schemas.google.com/apps/2006'>
<id>https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain</id>
<updated>2015-02-18T17:03:03.057Z</updated>
<link rel='next' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/?start=579841149621'/>
<link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain'/>
<link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain'/>
<link rel='self' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain'/>
<openSearch:startIndex>1</openSearch:startIndex>
<entry>
<id>https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621</id>
<updated>2015-02-18T17:03:03.056Z</updated>
<link rel='self' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621'/>
<link rel='edit' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621'/>
<apps:property name='resourceId' value='579841149621'/>
<apps:property name='resourceCommonName' value='Projector'/>
<apps:property name='resourceEmail' value='domain_key@resource.calendar.google.com'/>
</entry>
//99 more times:
<entry>
...
</entry>
您的脚本运行良好,但您正在浏览器中查看脚本的输出。浏览器将尝试将 XML 输出解析为 HTML,从而得出观察到的结果。更改您的代码,使其向浏览器指示响应为 XML,如下所示:
header('Content-type: application/xml');
if($output === false) { echo 'Curl error: ' . curl_error($ch); }
else { echo $output; }
或者使用命令行 PHP 解释器查看输出。
编辑:
您可能更乐意在 PHP 中解析 JSON;您可以通过将 alt=json
添加到请求中来获得 JSON 中的结果,如:
https://apps-apis.google.com/a/feeds/calendar/resource/2.0/<domain>/?alt=json
并将 $output = json_decode($output)
应用于输出;然后您可以访问所需的数据,例如第一个资源的邮箱地址,如下:
$output->feed->entry[0]->{'apps$property'}[2]->value
以下是 Hans Z. 为那些宁愿将资源作为数组处理的人提供的替代解决方案:
$array = json_decode($output, true);
$resources = $array['feed']['entry'];
foreach ($resources as $resource) {
$id = $resource['apps$property']['0']['value'];
$name = $resource['apps$property']['1']['value'];
$email = $resource['apps$property']['2']['value'];
//do something with data
}