像 jQuery 此类的库使开发人员创建站点的方式发生了革命性的变化,促进了大量可方便地添加至 HTML 的实用脚本的开发。微数据具有进一步推进此项革命的潜力,可以更加容易地创建可在任何站点上进行无缝工作的脚本,无论 HTML 模板有何变化。
例如,要在地图上显示计划的事件,jQuery 插件会集成 Google 地图,使在您站点上创建交互式地图变得简单。而您所要做的是以一种结构化格式(比如 JSON 或 CSV)创建一个包含位置的文件。但是,如果您还希望在页面上以 HTML 格式显示信息,拥有这种具有独立的结构化格式的数据可能是个难题。要同时去维护 HTML 和数据文件中的内容,您要么必须编写一段脚本来实现页面上 HTML 和数据文件之间转换,要么您必须重复执行工作。这种方法可能会很快导致 HTML 和数据文件不同步。
保持文件同步是使用像微数据和 RDFa 等 HTML 数据格式的一项重要优势,您可以像平常一样编写 HTML,然后在 HTML 标记中添加一些属性,使它和您的数据存储大小翻倍。因为这些 HTML 数据格式都是由 WHARWG 和 W3C 开发和批准的,人们已经构建了如何从 HTML 提取数据的构建工具,并且您可以在您的站点上轻松重用这些工具。
由于微数据只最近才开始受到人们的关注,所有只有少量已发布的插件提供了支持。有一个 jQuery UI Map 插件示例,它提供了上面所描述的地图。
您可以使用一小段的 HTML 以同时获得交互式事件地图和较出色的 SEO。
正如之前一篇文章(参见 参考资料 获得链接)所介绍的,微数据可与 Schema.org 词汇表中的术语结合使用,以帮助搜索引擎更好地理解您的内容。此方法使搜索引擎能够显示 Rich Snippet,后者可在搜索结果自身中显示关于页面的最重要信息。
为获得 Rich Snippet 而添加的注释可执行双重任务。除了能够更好地搜索结果,还可以将它使用在您自己的页面上实现更出色的显示。
您将使用一个 jQuery 插件完成此项任务。我在示例代码 下载 中提供了相关的文件,其中包含该插件略加修改的版本。
让我们创建一个全球的 DrupalCamp 事件清单。首先,创建一个包含两个事件的 HTML 页面,如 清单 1 中所示。
清单 1. 列出两个事件的基本 HTML
<!DOCTYPE html>
<head>
<title>Upcoming DrupalCamps</title>
</head>
<body id="doc">
<h1>Upcoming DrupalCamps</h1>
<!-- Event 1: DrupalCamp Toulouse -->
<div>
<h2><a href="http://example.com/drupalcamp_fr">DrupalCamp Toulouse 2011</a></h2>
<img src='images/drupalicon_fr.png' />
<p>Vous l’attendiez tous, le DrupalCamp Toulouse aura bien lieu,
réuni avec 2 autres événements sous la bannière
"Capitole du Libre": le DrupalCamp, une Ubuntu Party, une Akademy
(évènement KDE).</p>
<div>
ENSEEIHT, Toulouse, Haute-Garonne, FR
</div>
<div>
<time datetime="2011-11-26T09:00:00+01:00">November 26, 10:00am</time> –
<time datetime="2011-11-27T17:00:00+01:00">November 27, 6:00pm</time>
</div>
</div>
<!-- Event 2: DrupalCamp Ohio -->
<div>
<h2><a href="http://example.com/drupalcampohio">Drupalcamp Ohio 2011</a></h2>
<img src='images/drupalicon_oh.png' />
<p>The Central Ohio Drupal User Group (CODUG) is proud to announce
Ohio’s first Drupalcamp. On Saturday, December 3rd, we’ll hold an
all-day camp with keynote speaker, breakout sessions and Birds of Feather groups at The
Ohio State University’s Nationwide and Ohio Farm Bureau 4-H Center.</p>
<div>
The Ohio State University, Columbus, Ohio, US
</div>
<div>
<time datetime="2011-12-03T09:00:00-05:00">December 3, 9:00am</time> –
<time datetime="2011-12-03T17:00:00-05:00">5:00pm</time>
</div>
</div>
</body>
</html>
|
请注意,您使用一个特殊元素标记了日期。此元素是新时间元素,该元素是核心 HTML5 标准的一部分。它能够向页面添加准确时间,所以可由应用程序轻松地解析和应用。在此示例中,Google 使用这些时间元素从页面中选择另外 3 个事件以便在 Rich Snippet 中显示。请注意,在发布时,关于是否将时间元素更改为一种更加通用的数据元素的问题存在着争议。如果这一提议得以通过,“time” 将替换为 “data”,“datetime” 将替换为下面代码中的 “value”。
datetime 是以 YYYY-MM-DD 格式开始的。接下来,一个 “T” 将日期与时间分开,时间格式显示为 HH:MM:SS。然后提供相对于世界标准时间 (UTC) 的偏移。例如,冬天的法国,时间要比 UTC 提早一小时,所以要在 datetime 字符串末尾加上 ‘+01:00’ 的偏移量。冬天的 Ohio 要比 UTC 晚 5 小时,所以要在 datetime 字符串末尾添加 ‘-05:00’ 的偏移量。这种添加会使中部标准时间 2011 年 12 月 3 日上午 9 点得到机器可读的值 “2011-12-03T09:00:00-05:00”。
将文件保存到 Web 服务器中的 jquery-ui-map/demos 目录并将它加载到您的浏览器中。图 1 显示 清单 1 中描述的两个事件的详细信息。
图 1. 列出两个事件的基本页面
具有时间元素的页面包含少量机器可理解的信息。现在看看,如果这一添加发生更改,Google 会如何显示结果。转到 Google 的 Rich Snippets Testing Tool,输入您页面的 URL(参见 图 2)。您看到的不是事件详细信息,而是预览生成错误信息,上面显示着页面没有作者标记、Rich Snippet 标记或作者信息的。
图 2. Rich Snippets Testing Tool 中没有基本 HTML 的结果
即使 Google 知道您的页面列出了时间,但它也不知道这些时间是事件的开始和结束时间。要帮助 Google 理解这一点,您需要添加一些 Schema.org 术语(参见 清单 2)。关于使用微数据发布 Schema.org 标记已在之前的一篇文章有更详细地介绍(请参见 参考资料 获取链接)。
清单 2. 将每个事件的 <div> 添加到一个 Event 项中
<!-- Event 1: DrupalCamp Toulouse --> <div itemscope itemtype="http://schema.org/Event"> ... </div> <!-- Event 2: DrupalCamp Ohio --> <div itemscope itemtype="http://schema.org/Event"> ... </div> |
接下来将 url 和 name 属性添加到事件中。请注意,在名称两边添加一个 <span>,以留出空间来添加 itemprop 属性。您还要添加 image 属性。虽然在 Rich Snippet 中无需用到该 image,但在稍后就会用到它。
清单 3. 向事件添加 url 和 name 属性
<!-- Event 1: DrupalCamp Toulouse --> <div itemscope itemtype="http://schema.org/Event"> <h2><a href="http://example.com/drupalcamp_fr" itemprop="url"><span itemprop="name">DrupalCamp Toulouse 2011</span></a></h2> <img itemprop="image" src='images/drupalicon_fr.png' /> ... </div> <!-- Event 2: DrupalCamp Ohio --> <div itemscope itemtype="http://schema.org/Event"> <h2><a href="http://example.com/drupalcampohio" itemprop="url"><span itemprop="name">Drupalcamp Ohio 2011</span></a></h2> <img itemprop="image" src='images/drupalicon_oh.png' /> ... </div> |
现在您可以添加一个开始时间(可选项)和一个结束时间。因为您使用了时间元素,所以您已经拥有开始时间和结束时间的机器可读值。您只需添加 Schema.org 术语来让 Google 知道各种值的对应关系(参见 清单 4)。
清单 4. 在时间元素上添加 startDate 和 endDate 属性
<!-- Event 1: DrupalCamp Toulouse -->
<div itemscope itemtype="http://schema.org/Event">
...
<div>
<time itemprop="startDate" datetime="2011-11-26T09:00:00+01:00">November 26,
10:00am</time> –
<time itemprop="endDate" datetime="2011-11-27T17:00:00+01:00">November 27,
6:00pm</time>
</div>
</div>
<!-- Event 2: DrupalCamp Ohio -->
<div itemscope itemtype="http://schema.org/Event">
...
<div>
<time itemprop="startDate" datetime="2011-12-03T09:00:00-05:00">December 3,
9:00am</time> –
<time itemprop="endDate"
datetime="2011-12-03T17:00:00-05:00">5:00pm</time>
</div>
</div>
|
再次在 Testing Tool 中测试该页面。因为 URL 指向一个与基本 URL 不同的域,您会看到阻止 Rich Snippet 显示的警告(参见 图 3)。
图 3. 阻止 Rich Snippet 显示的警告
Google 要求事件的链接指向相同域中的页面。这一要求旨在预防垃圾信息。如果您搜索 example.com 并将其替换为您的域,然后再次进行测试,您应该会看到 Rich Snippet 的显示,如 图 4 所示。
图 4. 同时显示了两个事件及其开始日期的 Rich Snippet
请注意,即使测试工具向您显示了一个 Rich Snippet,您也无法保证在真实的搜索结果中会显示 Rich Snippet。您必须向 Google 申请检查您的站点,Google 才会在搜索结果中启用您页面的 Rich Snippet 输出。更多相关信息请查看常见问题解答。
因为 DrupalCamps 在全球各地举办,所以您的访问者希望有个地图来显示合理旅行范围内所发生的事件。要获得地图,只需添加另外一些信息。
首先,设置地图的显示。在文档中添加一个 <div> 以将地图放置在页面标题下和事件清单上(参见 清单 5)。
清单 5. 添加地图 <div>
<body id="doc">
<h1>Upcoming DrupalCamps</h1>
<div>
<div id="map_canvas"></div>
</div>
<!-- Event 1: DrupalCamp Toulouse -->
|
您需要添加一些 JavaScript 文件来将此 <div> 转换为一种交互式地图。另外还要添加一些 CSS 文件,为
#map_canvas
<div> 提供一个高度,使您可以看到它。本地文件包含在源代码中(参见 下载)。
清单 6. 添加外部 CSS、JavaScript 库和内联 jQuery
<head> <title>Upcoming DrupalCamps</title> <!-- External Stylesheets --> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.2.0/build/cssreset/reset-min.css" /> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.2.0/build/cssbase/base-min.css" /> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.2.0/build/cssfonts/fonts-min.css" /> <link rel="stylesheet" type="text/css" href="css/main.css" /> <!-- Google Maps API and jQuery, served by Google --> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script> <!-- jQuery UI Maps files for placing markers and for parsing Microdata --> <script type="text/javascript" src="../web/jquery.fn.gmap.js"></script> <script type="text/javascript" src="../ui/jquery.ui.map.services.js"></script> <script type="text/javascript" src="../ui/jquery.ui.map.microdata.js"></script> ... |
然后添加一个 jQuery 代码块,它会在页面初始化时获取 #map_canvas div 并将其转换为一个地图(参见 清单 7)。稍后将更详细地介绍此功能。
清单 7. 初始化地图
...
<!-- Grab the #map_canvas div and turn it into a map -->
<script type="text/javascript">
$(function() {
map = $('#map_canvas');
map.gmap().bind('init', function () {
});
});
</script>
</head>
|
重新加载页面时,您将会看到地图(如 图 5 所示)。它还未标记任何事件,您还需要添加更多信息来显示这些事件。
图 5. 没有任何标记的基本地图
在将标记添加到地图之前,您需要在微数据中添加事件的位置。暂时先将每个地址视为单个字符串。但是,地址包含多个不同的部分,并且您希望在微数据中表达此结构,即使以后对 HTML 结构进行更改也能轻松一致地获得正确的值。
首先,添加 location 属性,它会为它的值获得一个 Place(参见 清单 8)。
清单 8. 向事件添加 location 属性
<!-- Event 1: DrupalCamp Toulouse -->
<div itemscope itemtype="http://schema.org/Event">
...
<div itemprop="location" itemscope itemtype="http://schema.org/Place">
ENSEEIHT, Toulouse, Haute-Garonne, FR
</div>
...
</div>
|
Place 可以拥有一个姓名和一个通信地址。通信地址拥有自身的属性项,其中包括街道地址、城市 (addressLocality)、州 (addressRegion) 和 addressCountry (应该是一个二位字母代码 ISO 3166-1 alpha-2)。清单 9 使用 span 标记将这些属性隔开。
清单 9. 使用 span 标记
<!-- Event 1: DrupalCamp Toulouse -->
<div itemscope itemtype="http://schema.org/Event">
...
<div itemprop="location" itemscope itemtype="http://schema.org/Place">
<span itemprop="name">ENSEEIHT</span><br />
<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<span itemprop="streetAddress">Rue Sylvain Dauriac</span><br />
<span itemprop="addressLocality">Toulouse</span>,
<span itemprop="addressRegion">Haute-Garonne</span>,
<span itemprop="addressCountry">FR</span>
</span>
</div>
...
</div>
|
您可采用相同方式格式化其它事件的地址。
您已准备好向地图中添加标记。首先,将页面上的微数据解析为一个可以使用的对象。为此,指定哪种类型的顶级项是您想要的数据来源。微数据中的顶级项可视为根项;这些项不是任何其它项的属性,而是拥有自己的属性。指定 http://schema.org/Event。这会为每个事件返回一个对象(参见 清单 10)。
清单 10. 将微数据解析为对象
<script type="text/javascript">
$(function() {
map = $('#map_canvas');
map.gmap().bind('init', function () {
// Process the microdata for each Event into an object.
map.gmap('microdata', 'http://schema.org/Event', function(result, item, index) {
window.console.log(result);
});
});
});
</script>
|
您可以在 Firefox 和 Chrome 等浏览器中看到在 JavaScript 控制台中由微数据创建的对象。微数据中的每项被转换成一个具有自己的属性对象的对象,其中包含来自该项的所有 itemprop 值。因为微数据中的属性可能具有多个值,所以将 itemprop 值当作数组来处理(参见 图 6)。
图 6. 在 Chrome JavaScript 控制台中检查对象
这个对象拥有您获得位置的地理坐标所需的所有属性,您需要在事件上放置该位置的标记。要获得此信息,从对象中提取地址的各部分并将它们组合成一个 Google 能读取的地址字符串。您然后可使用 Google 的 Geocoder 获得此地址的坐标。jQuery UI Map 库提供了一个包装器函数,您可以使用它运行 Geocoder 请求。
请注意,如果您获得了一个未定义的错误,请仔细检查以确保您在所列出的所有事件上拥有所有需要的属性(参见 清单 11)。
清单 11. 运行地址的 Geocoder 请求
<script type="text/javascript">
$(function() {
map = $('#map_canvas');
map.gmap().bind('init', function () {
// Process the Microdata for each Event into an object.
map.gmap('microdata', 'http://schema.org/Event', function(result, item, index) {
// Traverse from the Event to the Place and from the Place to the
// Address to get the properties.
var placeName = result.properties.location[0].properties.name[0];
var streetAddress =
result.properties.location[0].properties.address[0].properties.streetAddress[0];
var city =
result.properties.location[0].properties.address[0].properties.addressLocality[0];
var state =
result.properties.location[0].properties.address[0].properties.addressRegion[0];
var country =
result.properties.location[0].properties.address[0].properties.addressCountry[0];
// Join the address parts into a comma-separated string.
var address = [placeName, city, state, country].join(', ')
// Run the Geocoder request for the address.
map.gmap('search', {'address': address } , function(result, status) {
window.console.log(result);
// We will place the marker here.
});
});
});
});
</script>
|
如果在控制台中查看结果,您将看到该服务返回了一个或多个与您的地址匹配的位置。您将近使用第一个位置,因为这是最佳的匹配值。该对象有一个 geometry 属性,其中包含您需要的地理坐标信息(参见 清单 12)。
清单 12. 放置标记
<script type="text/javascript">
$(function() {
map = $('#map_canvas');
map.gmap().bind('init', function () {
// Process the Microdata for each Event into an object.
map.gmap('microdata', 'http://schema.org/Event', function(result, item, index) {
// Traverse from the Event to the Place and from the Place to the
// Address to get the properties.
var placeName = result.properties.location[0].properties.name[0];
var streetAddress =
result.properties.location[0].properties.address[0].properties.streetAddress[0];
var city =
result.properties.location[0].properties.address[0].properties.addressLocality[0];
var state =
result.properties.location[0].properties.address[0].properties.addressRegion[0];
var country =
result.properties.location[0].properties.address[0].properties.addressCountry[0];
// Join the address parts into a comma-separated string.
var address = [placeName, city, state, country].join(', ')
// Run the Geocoder request for the address.
map.gmap('search', {'address': address } , function(result, status) {
if (status == google.maps.GeocoderStatus.OK) {
// Create a LatLng object.
var lat = result[0].geometry.location.lat();
var lng = result[0].geometry.location.lng();
var latlng = new google.maps.LatLng(lat, lng);
// Place the marker.
var markerOptions = {
'bounds':true,
'position': latlng
};
map.gmap('addMarker', markerOptions);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
});
});
});
</script>
|
当重新加载页面时,您应该看到如 图 7 中所示的位置标记。
图 7. 放置在地图上的标记
如果用户可单击标记来获得事件详细信息,比如事件的日期和链接,地图会变得更有用。添加此功能并不难。
首先,从解析的微数据中提取您想要的关于该事件的附加信息(参见 清单 13)。
清单 13. 获得补充信息
<script type="text/javascript">
$(function() {
map = $('#map_canvas');
map.gmap().bind('init', function () {
// Process the Microdata for each Event into an object.
map.gmap('microdata', 'http://schema.org/Event', function(result, item, index) {
var eventName = result.properties.name[0];
var logo = result.properties.image[0];
var url = result.properties.url[0];
var start = result.properties.startDate[0];
...
});
});
</script>
|
在您将标记添加到地图之前,创建一个包含事件详细信息的 HTML 代码块(参见 清单 14)。
清单 14. 创建信息窗口的 HTML
// Run the Geocoder request for the address.
map.gmap('search', {'address': address } , function(result, status) {
if (status == google.maps.GeocoderStatus.OK) {
// Create a LatLng object.
var lat = result[0].geometry.location.lat();
var lng = result[0].geometry.location.lng();
var latlng = new google.maps.LatLng(lat, lng);
var eventDetails = '';
eventDetails += '<div class="iw">';
eventDetails += '<img src="'+logo+'"></img>';
eventDetails += '<h2><a href="'+url+'">'+eventName+'</a></h2>';
eventDetails += new Date(start).toDateString();
eventDetails += '</div>';
// Place the marker.
...
|
然后将事件详细信息添加到您创建的标记。使用 jQuery 的 .click 来表明您希望在某人单击该标记时运行哪个函数。在该函数中,使用 jQuery UI Maps 库提供的 openInfoWindow 帮助器函数来构建窗口,并传入您的 HTML 作为该窗口的内容(参见 清单 15)。
清单 15. 添加 Info Window 作为单击事件
// Place the marker.
...
map.gmap('addMarker', markerOptions).click( function() {
map.gmap('openInfoWindow', { 'content': eventDetails }, this );
});
|
完成此任务后重新加载,然后单击该标记。您将看到弹出了一个包含事件详细信息的窗口(参见 图 8)。
图 8. 单击事件标记
要改善外观,添加一些 CSS 规则。我在可下载的示例代码中添加了这些规则(参见 下载)。最后,您的地图类似于 图 9。
图 9. 最终的地图
微数据通过利用 jQuery 插件使您可以轻松地以动态方式在您页面上使用数据,比如在 Google 地图上。微数据规范探讨了通用脚本,该脚本可用在不同和不相关站点上作为插件。微数据还使通过组合来自多个不同站点的数据来创建新应用程序的过程变得简单。在下一篇文章中,我将演示如何使用 Drupal 创建这样一个应用程序。
| 描述 | 名字 | 大小 | 下载方法 |
|---|---|---|---|
| 文章源代码 | jquerymicrodatapt1_source.zip | 464KB | HTTP |
学习
- ISO 3166-1 (Wikipedia):查找关于二位字母代码 (ISO 3166-1 alpha-2) 的信息。
- Schema.org:了解关于该模式集合的更多信息,它们是一些 HTML 标记,可使网站管理员以主要搜索提供商认可的方式标记他们自己的页面。
- schema.org 入门:在这些教程中,学习如何在 Schema.org 站点上放置 schema.org 术语。
- Itemtype URL:访问 itemtype URL(比如 http://schema.org/Movie),查找您可以用在 schema.org 项上的属性。
- The Semantic web, Linked Data and Drupal, Part 1: Expose your data using RDF(Lin Clark,developerWorks,2011 年 4 月):使您的 Web 数据更具有互操作性,您的数据共享更具高效性。示例展示了如何使用 Drupal 7,通过使用 RDF 公开内容来发布 Linked Data。
- The Semantic web, Linked Data and Drupal, Part 2: Combine linked datasets with Drupal 7 and SPARQL Views(Stéphane Corlosquet 和 Lin Clark,developerWorks,2011 年 5 月):学习如何在数据 Web 上使用现有的 Linked Data,以及如何使用来自不同端点的数据丰富 Drupal 7 站点。
- Scientific American article on the Semantic web:阅读这篇由 Tim Berners-Lee、James Hendler 和 Ora Lassila 所撰写的开创性文章。
- Linked Data:阅读 Tim Berners-Lee 参与的有关 Linked Data 的 ReadWriteWeb 访谈。
- Linked Data Design Issues:从 Tim Berners-Lee 那里了解有关链接的数据的更多信息。
- Rich snippets (microdata, microformats, and RDFa) - Webmaster Tools Help:了解 Google Rich Snippet 的更多信息和如何标记 Web 内容来明确表明数据类型,比如酒店名称、地址或评分。
- Implement Semantic web standards in your Web site(Rob Crowther,developerWorks,2008 年 5 月):使用 PHP 和 MySQL 创建一个简单的社交网站,实现 hCard 和 Friend of a Friend (FOAF) 等语义 Web 标准作为语义统一资源标识符 (URI) 模式中的一部分。
- FOAF Vocabulary Specification 0.98:探讨 FOAF 语言,定义为一个使用 W3C EDF 技术的已命名属性和类词汇表。
- Dublin Core Metadata Initiative (DCMI):了解该开放组织,该组织主要从事于支持广泛用途和业务模型的可互操作元数据标准的开发。
- SIOC (Semantically-Interlinked Online Communities) Core Ontology Specification:了解描述语义 Web 上各在线社区(比如消息版、Wiki 或网络广播)信息所需的主要概念和属性。
- SPARQL Explorer for http://dbpedia.org/sparql:尝试该 Web 提供的一个演示查询接口。
- developerWorks 中国网站 Web 开发专区:查找有关各种基于 Web 的解决方案的文章。
-
XML 新手入门:获取您学习 XML 所需要的资源。
- IBM InfoSphere Master Data Management Server 商业价值概述:查找您提升 XML 领域的技能(包括 DTDs、模式和 XSLT)所需的资源。访问 XML 技术库,获得大量的技术文章和技巧、教程、标准和 IBM 红皮书。
- IBM XML 认证:了解如何成为 XML 领域及相关技术的 IBM 认证开发人员。
- developerWorks 技术活动 和 网络广播:随时关注这些领域的最新技术。
- Twitter 上的 developerWorks:立即关注 developerWorks tweet。
- developerWorks 播客:收听面向软件开发人员的有趣访谈和讨论。
- 演示如何用 WebSphere Studio 快速开发Web Services:观看演示,包括面向初学者的产品安装和设置演示,以及为经验丰富的开发人员提供的高级功能。
获得产品和技术
- jQuery UI Map:下载最新版本,并使用地图上的 jQuery 单击事件和标记从您站点上的微格式、RDFa 或微数据填充一个地图。
- Google 的 Rich Snippets Testing Tool:测试 Rich Snippet。
-
Google 的 Rich Snippets Testing Tool:测试您的 schema.org 标记。
- Live Microdata 测试工具:获得 Opera 开发人员 Philip Jägenstedt 创建的另一个工具来测试微数据。
- IBM 产品评估试用版软件:下载或 IBM SOA 人员沙箱 ,并开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。
讨论
- developerWorks 概要信息:立即创建自己的概要信息,并 设置一个关注列表。
- XML 专区讨论论坛:参与任何一个 XML 相关讨论。
- developerWorks 中文社区:查看开发人员推动的博客、论坛、群和 Wiki,并与其他 developerWorks 用户交流。
