---
title: "使用 MapForce 处理 Groupon API 的方法（第二部分）"
date: "2011-08-16"
categories: 
  - "data-integration"
tags: 
  - "altova-xmlspy"
  - "data-integration"
  - "data-mapping"
  - "mapforce"
  - "missionkit"
  - "xml-editor"
  - "xml-schema"
  - "xmlspy"
description: 探索如何使用 Altova MapForce 能够有效地处理 Groupon API，包括动态数据映射、查询执行以及输出过滤策略。
---
Status: #blog

Tags:  #altova-xmlspy #data-integration #data-mapping #mapforce #missionkit #xml-editor #xml-schema #xmlspy

Categories: [data-integration](/blog/zh/category/data-integration.md)
# 使用 MapForce 处理 Groupon API 的方法（第二部分）

在[本系列的第一部分](https://www.altova.com/blog/2011/08/processing-groupon-api-with-altova.html)中，我们介绍了如何将[Altova MapForce](https://www.altova.com/zh/mapforce.html)连接到Groupon API。我们首先向API请求了Groupon各个分部的列表，然后使用该列表来创建针对每个分部所有当前优惠活动的API查询。在本部分，我们将执行这些"/deals"查询，并筛选响应以获取最有趣的数据。我们之前构建的"/deals"查询列表如下： 

[![Altova MapForce 生成的 Groupon/优惠活动相关查询列表](https://lh3.ggpht.com/-DuCz6NmnbUQ/Tkkced-kKNI/AAAAAAAAAdc/6GOLTV7epMk/clip_image001_thumb.png?imgmax=800 "List of Groupon /deals queries generated by Altova MapForce")](http://lh3.ggpht.com/-2Z-nwIU-LKI/TkkceMyFDeI/AAAAAAAAAdY/kDFXB-IdDhw/s1600-h/clip_image0013.png) 

为了处理所有查询，我们可以将查询列表作为动态文件输入，连接到一个新的映射组件。上次我们需要一个新的组件时，我们直接将一个API/divisions查询放入映射中，让MapForce自动生成XML Schema。我们可以在这里做同样的事情，将一个API/deals查询作为XML输入文件放入映射中。不过，有一个小问题：虽然Groupon API的在线文档清楚地描述了我们可以执行的查询，但它对将返回的信息却含糊不清。在我们将数十个查询发送给API以获取所有当前的优惠信息之前，我们可能需要了解更多关于将返回的数据的信息。 

**我们来谈谈条件** 

正如约基·贝拉所说，仅仅通过观察，你就能了解到很多东西。 让我们首先在 [XMLSpy](https://www.altova.com/zh/xmlspy.html) 中运行一个 "/deals" 查询。 这样，我们就可以在导入大量数据之前，先检查针对一个部门的查询结果。 XMLSpy 的“文件/打开”菜单中包含了与之前在 MapForce 中使用的相同的“切换到 URL”选项。 如果我们输入一个针对覆盖大型都市区域（例如达拉斯）的 "/deals" API 查询，我们很可能会获得足够多的交易记录，从而可以推断出整个数据集的特征。 XMLSpy 会像打开本地文件一样，以文本视图打开 "/deals" API 查询的响应： 

[![以下是从对Groupon/优惠活动咨询的回复中提取的示例，以XMLSpy软件展示](https://lh5.ggpht.com/-yuh3IG08N-M/TkkceylAHBI/AAAAAAAAAdk/v85ydqJD_IY/clip_image002_thumb.png?imgmax=800 "Response to a Groupon /deals query, shown in XMLSpy")](http://lh6.ggpht.com/-Eb1X5J799Yo/Tkkce1ixmfI/AAAAAAAAAdg/8gDhEldnKco/s1600-h/clip_image0023.png) 

正如我们预料到的，当我们请求一个部门的所有交易数据时，我们获得了大量的数据。一种快速分析这些数据结构的方法是，使用 XMLSpy 的 DTD/Schema 菜单选项，从 XML 文件生成一个 .xsd 文件。以下展示的是基于对达拉斯（Dallas）的 /deals 查询响应而生成的完整 .xsd 文件的简化视图： 

[![由 XMLSpy 工具，基于 Groupon 的查询语句生成的 XSD 文件](https://lh5.ggpht.com/-kphWHOIh5FY/Tkkcfq0x1rI/AAAAAAAAAds/wP2tm-rh3sU/clip_image004_thumb.jpg?imgmax=800 "An XML Schema generated by XMLSpy from the Groupon query")](http://lh5.ggpht.com/-nFAolywZOlU/TkkcfVfixfI/AAAAAAAAAdo/ixbMzb4FjMM/s1600-h/clip_image0043.jpg) 

我们可以进一步深入研究，就像瑜伽大师所说的那样，仿佛一切都在重演。 详细审查 XML Schema 的所有元素，会发现一些有趣的异常情况。 例如，存在两个名为 "redemptionLocation" 的元素，但它们的定义却不同。 第一个元素包含一系列子元素： 

[![首次使用“兑换地点”元素](https://lh3.ggpht.com/-3_iJQ8vMJv4/TkkcgPTVebI/AAAAAAAAAd0/H5Y0Y4UhYag/clip_image005_thumb.png?imgmax=800 "First use of the remdemptionLocation element")](http://lh5.ggpht.com/-Ds65S--pYGo/Tkkcf6t47qI/AAAAAAAAAdw/ctfBMJDvkSI/s1600-h/clip_image0053.png) 

第二种情况定义为一个简单的字符串： 

[![第二次使用“兑换地点”元素](https://lh5.ggpht.com/-0f6ygtVStac/TkkcgsChc0I/AAAAAAAAAd8/kP4MfwN-nbo/clip_image006_thumb.png?imgmax=800 "Second use of the remdemptionLocation element")](http://lh6.ggpht.com/-TnjeC_B-xwo/TkkcgaD3N4I/AAAAAAAAAd4/QPsqdCH3_G8/s1600-h/clip_image0063.png) 

重新检查达拉斯的XML数据，并搜索“redemptionLocation”字段，可以找到以下示例： 

[![一个赎罪的例子。 (位置：响应内容中的某个位置)](https://lh3.ggpht.com/-_jeVWegS2_E/TkkchCwxMBI/AAAAAAAAAeE/-WTenar_XWk/clip_image007_thumb.png?imgmax=800 "One example of redemptionLocation in the body of the response")](http://lh6.ggpht.com/-u8aUGljt0ak/Tkkcgyld0pI/AAAAAAAAAeA/BZPUZ9pzTvM/s1600-h/clip_image0073.png) 

并且： 

[![一个赎罪的例子。 (位置：响应内容中的某个位置)](https://lh4.ggpht.com/-NmUZPlUkkZI/TkkchXZRqgI/AAAAAAAAAeM/PCRMkYPZYgE/clip_image008_thumb.png?imgmax=800 "One example of redemptionLocation in the body of the response")](http://lh6.ggpht.com/-0qhiOg-24LI/TkkchKG4nOI/AAAAAAAAAeI/LP_XSf5LwCM/s1600-h/clip_image0083.png) 

并且：

[![一个赎罪的例子。 (位置：响应内容中的某个位置)](https://lh3.ggpht.com/-NwOgfSsxWmo/Tkkch7Nu2_I/AAAAAAAAAeU/DxwKHSBh6i8/clip_image009_thumb.png?imgmax=800 "One example of redemptionLocation in the body of the response")](http://lh4.ggpht.com/-ZPjMwCObxk0/TkkchpHYZiI/AAAAAAAAAeQ/wlLAu6yhnyY/s1600-h/clip_image0093.png) 

现在这非常有趣，因为 `redemptionLocation = "online"` 标识的是可以在任何地方兑换的优惠，而不是必须到广告宣传的特定实体店进行兑换。 假设我们对所有分部的 `/deals` API 进行查询，并提取所有在线优惠的列表，那将是一个非常庞大的 Groupon 平台！

** 只请求您需要的信息 **
Groupon 的 `/deals` API 查询支持一个可选参数 `&show=`, 允许用户限制返回的数据。 使用此参数可以节省带宽，并减少数据转换的计算时间，因为它会从 API 响应中移除不需要的数据。 我们可以通过只包含最有趣的信息来简化我们的最终结果，包括每个优惠对应的 Groupon 网页链接。 在从生成的达拉斯模式中移除不需要的元素后，我们最终用于总结在线优惠的版本如下： 

[![XMLSpy 中生成的简化版 Groupon XSD 文件的结构图](https://lh4.ggpht.com/-iwVlq7FJKaI/TkkciR_RWlI/AAAAAAAAAec/40tefse9cdU/clip_image010_thumb.png?imgmax=800 "XMLSpy Schema diagram of the simplified Groupon xsd file")](http://lh3.ggpht.com/-lj5Ou5l1F2I/TkkciBixtCI/AAAAAAAAAeY/ZPWD35XiU1Q/s1600-h/clip_image0103.png) 

当我们向 MapForce 映射添加 "&show=" 参数，以仅请求包含在简化 XML 模式中的元素时，查询语句会呈现如下形式：

[![修改后的查询列表，包含 "&show=" 参数](https://lh6.ggpht.com/-U_NgQfTyMSI/Tkkci5k9peI/AAAAAAAAAek/a_K8X4pljQ8/clip_image011_thumb.png?imgmax=800 "Modified list of queries with the &show= parameter")](http://lh5.ggpht.com/-k15Fug8YlDM/TkkciuNh8TI/AAAAAAAAAeg/z-vZ8UXA9uE/s1600-h/clip_image0113.png) 

现在，我们可以将修改后的 .xsd 文件导入到映射配置中，并将 API/交易查询列表作为动态输入连接起来。我们不需要删除之前用于收集查询列表的文本文件，因为该文件可能在未来的调试中仍然有用。 

[![MapForce 动态输入文件映射](https://lh5.ggpht.com/-1UHiT_Wo7wk/TkkcjQ4eRUI/AAAAAAAAAes/cIED363B0lM/clip_image012_thumb.png?imgmax=800 "Mapforce dynamic input file mapping")](http://lh5.ggpht.com/-yVH1tV-Hxww/TkkcjLLDrYI/AAAAAAAAAeo/kjoWneA91N8/s1600-h/clip_image0123.png) 

这些更改完成了数据映射的输入部分。 

**定义数据转换的输出结果** 

在 XMLSpy 中，我们可以对输入 XML 模式进行进一步的修改，从而设计一个新的版本用于输出 

[![XMLSpy 中用于输出文件的 XSD 模式图](https://lh4.ggpht.com/-Ay_3WyFqFA8/Tkkcj1lL4eI/AAAAAAAAAe0/MbDOLQIx_eY/clip_image013_thumb.png?imgmax=800 "XMLSpy schema diagram of the output file xsd")](http://lh3.ggpht.com/-GpaXSUZ0Rvc/TkkcjsBzMVI/AAAAAAAAAew/8C0GzH_Y22A/s1600-h/clip_image0133.png) 

我们删除了“响应元素”，因为它没有提供任何有价值的信息，并且移除了“兑换地点”元素，因为我们不打算将其包含在输出结果中。此外，我们还添加了一个“日期”元素，用于记录时间戳，因为我们的输出文件将是不断变化的数据的快照。 

在 XMLSpy 中保存此版本的 .xsd 文件后，我们可以将其导入到 MapForce 的映射配置中。下图显示了映射配置的输出部分，其中部分组件已连接。位于顶部的过滤器读取 "redemptionLocation" 元素，用于选择仅限在线的优惠活动，而 "now" 函数用于插入当前日期

[![MapForce 输出文件映射的局部视图](https://lh3.ggpht.com/-dCMzbcgoV7o/TkkckSog8tI/AAAAAAAAAe8/E3WXT_hufz0/clip_image014_thumb.png?imgmax=800 "Partial view of the MapForce output file mapping")](http://lh4.ggpht.com/-Bw3lJz0IGRY/TkkckIAeytI/AAAAAAAAAe4/wRJ4iBcFJVY/s1600-h/clip_image0143.png) 

我们在输出 XML 模式的最后一次修改是，将几个元素的类型从 dateTime、Boolean 和 integer 更改为字符串类型，以便允许输入更具描述性的文本。以下是映射的完整定义，以及与输出组件的最终连接： 

[![Mapforce 数据映射工具，用于 Groupon API](https://lh4.ggpht.com/-nqTnqO-22FQ/Tkkck9jjGMI/AAAAAAAAAfE/S98nV4FP7uE/clip_image015_thumb.png?imgmax=800 "Mapforce data mapping for the Groupon API")](http://lh5.ggpht.com/-Pb7a5H2UpFs/TkkcknIB9_I/AAAAAAAAAfA/rsYL1Q1NHUk/s1600-h/clip_image0153.png) 

**现在，让我们来看看最终成果** 

当我们点击“输出”按钮时，MapForce 会使用其内置的执行引擎，从头到尾处理整个数据转换过程。以下是具体步骤：

- 运行 `/divisions` 查询，以获取当前的分区列表
- 将字符串连接起来，以构建包含所有部门的 "/deals" 查询列表
- 运行 `/deals` 查询，以生成动态数据，供输入组件使用
- 筛选在线优惠信息，生成输出组件，执行剩余的映射函数，并在处理完所有优惠信息后添加时间戳

MapForce 可以在几秒钟内完成所有这些步骤，并生成一个输出文件，其中包含一系列交易数据，其格式如下： 

[![来自 MapForce 映射工具处理的 Groupon API 数据输出](https://lh5.ggpht.com/-nLw5_EH7G-c/TkkclUU6KzI/AAAAAAAAAfM/_GNvvf-Mlqc/clip_image016_thumb.png?imgmax=800 "Output data from the MapForce mapping for the Groupon API")](http://lh6.ggpht.com/-GkEs7wJOvcs/TkkclJCUb0I/AAAAAAAAAfI/eXjcgRriFbY/s1600-h/clip_image0163.png)

在系列文章的第三部分，我们将设计一个样式表，该样式表能够自动将我们地图生成的 XML 输出转换为 HTML，从而在网页浏览器和移动设备上呈现出美观的效果。 很高兴与您在球场相见，尤吉！ 

XMLSpy和MapForce可以捆绑在价格优惠的Altova MissionKit中。 亲自体验一下，使用MissionKit将数据从Web API转换有多么简单——[下载免费的30天试用版！](https://www.altova.com/zh/download/missionkit/software_development_tools_enterprise.html) 

**编辑语：** 我们之前推出的一系列关于如何从 Groupon API 获取数据的文章，分为三个部分。您可以点击以下链接查看：第一部分 [使用 Altova MapForce 处理 Groupon API](https://www.altova.com/blog/2011/08/processing-groupon-api-with-altova.html) 描述了如何通过从多个网址收集数据来创建动态输入。 [使用 MapForce 处理 Groupon API 的方法（第二部分）](https://www.altova.com/blog/2011/08/processing-groupon-api-with-mapforce.html) 它描述了我们如何从API中筛选数据，并定义输出格式，以便只提取最重要和有趣的信息。 [处理 Groupon API – 第 3 部分](https://www.altova.com/blog/2011/08/processing-groupon-api-part-3.html) 它描述了如何将输出格式化为单个HTML文档，该文档针对桌面设备和移动设备进行了优化，并介绍了自动化重复执行的方法。
