XML は Web の SGML ですが、XML コミュニティほど Web 上で目立つようにはなっていません。 Web における XML の最も著名な成果である XHTML は、政治や委員会の設計に巻き込まれており、XForms や SVG などの他の野心的で技術的に健全な仕様は、使用率の低さに悩まされています。 XML は、XML 形式の Web フィード (RSS タイプや Atom など) の人気など、予期せぬ方法で Web 上で成功することがあります。
よく使われる略語
Ajax: 非同期JavaScript + XML
API: アプリケーションプログラミングインターフェース
CSS: カスケードスタイルシート
DOM: ドキュメントオブジェクトモデル
HTML: ハイパーテキストマークアップ言語
RSS: Really Simple Agg規制
SGML: 標準汎用マークアップ言語
SVG: スケーラブル ベクター グラフィックス
URI: ユニフォーム リソース識別子
URL: ユニフォーム リソース ロケーター
W3C: World Wide Web コンソーシアム
XHTML: 拡張可能なハイパーテキスト マークアップ言語
XML: 拡張可能なマークアップ言語
Web 上の他のテクノロジーと同様、Web 上の XML はブラウザー中心ですが、Web 上の XML の処理に関するほとんどの議論はサーバー側に焦点を当てています。 「developerWorks Firefox と XML」シリーズでは、Firefox ブラウザーで XML を使用するいくつかの方法を説明します。残念ながら、ブラウザ間での XML の処理は、ブラウザ間での HTML の処理よりもさらに奇妙です。これが、Web 上の XML 処理の多くがサーバー側の比較的安全な領域に留まっている理由の 1 つです。
多くの動的 HTML 開発者は、ブラウザー間の苦痛や、ブラウザー間のスクリプト作成の癖にうんざりしています。いくつかの優れた JavaScript ライブラリの出現により、開発者の作業は容易になりました。これらのライブラリの中で最も人気のあるものの 1 つは jQuery で、developerWorks のいくつかの記事で取り上げられています。これらの大きな落とし穴を回避する方法を知っていれば、jQuery を使用して XML を処理することもできます。この記事では、現実世界のシナリオで jQuery と XML を一緒に使用する方法、Atom Web フィードの使用方法、jQuery で XML を処理するための実践的なパターンを紹介し、現実世界の不幸な問題を解決する方法を示します。 XML、XML 名前空間、HTML、JavaScript、および jQuery ライブラリについての基本的な理解が必要です。
XML 名前空間の問題
最初に最も深刻な問題について説明します。 jQuery は XML 名前空間の問題を完全には解決しません。このよく知られた問題は長い間存在しており、さまざまな解決策が試みられてきましたが、満足のいく結果は得られませんでした。理想的な解決策は、jQuery の CSS レベル 3 名前空間セレクターのサポートを活用することです。これにより、次のような新しいセレクターが追加されます:
@namespace ex url(http://example.com);
ex|quote {font-weight:太字}
最初の行は http://example.com 名前空間の接頭辞宣言で、2 行目は新しい名前空間コンポーネントを使用する型セレクターであり、宣言された接頭辞とローカル名で区切られています。 。残念ながら、jQuery はこのアプローチをサポートしていないため、名前空間の問題に対処するためにさまざまなアプローチが取られています。
プレフィックスの重要性
最も一般的なハックの 1 つは、jQuery で XML と名前空間を処理するときに名前空間を無視し、完全な qname (プレフィックスとローカル部分) を選択することです。
$(xml).find("x\:quote").each(function() {
//process each node
});
このコードは、jQueryのノード名の概念、つまりDOMのnodeNameを通じて選択します。属性。これには、jQuery セレクターの予約記号であるコロンが含まれており、バックスラッシュでエスケープする必要があります。バックスラッシュは JavaScript スクリプトの予約記号であり、ペアで指定する必要があります。このハックは、異なる接頭辞を使用する名前空間と同等のドキュメントでは機能しません。
属性フィルターの使用
一部の人々は、次の方法のバリエーション、つまり疑似属性ノード名に対して jQuery 属性フィルターを使用して成功したと言われています:
$(xml).find("[nodeName=x] :quote]") .each(function() {
//process each node
});
1.3.xより前のバージョンのjQueryを使用する場合は、nodeNameの前に@を追加する必要があります。ただし、これを行うと、前のセクション「プレフィックスのマスカレードの重要性」で説明したアプローチと同じ基本的な問題が発生します。これにより、多くの実際の名前空間シナリオが破壊されます。私は次のバリエーションを試してみましたが、これはより意味のあるものです:
$(xml).find("[namespaceURI='http://example.com'][localName='quote']")
.each(function () {
//process each node
});
残念ながら、これは機能しません。
良いプラグインを探しています
这种混乱不完全是 jQuery 的错。DOM 为寻找节点提供了有效的方法:getElementsByTagName 和 getElementsByTagNameNS。后者旨在感知名称空间,接受名称空间的 URI 并忽略前缀,但遗憾的是,尽管其他浏览器都支持它,但 Microsoft® Internet Explorer® 除外。然而,jQuery 的目的是处理此类浏览器问题,以便消除人们的此类烦恼。一种可能的、牵强的理由是,jQuery 很大程度上以 CSS 作为其选择器的基础,并且即使是 W3C CSS Level 3 名称空间选择器也无法使它通过工作草案阶段。jQuery bug #155,“Get Namespaced Elements in XML Documents”,涵盖了这些问题,但是问题在 3 年之内没有得到解决。
Ryan Kelly 遇到此问题并做了一次大胆的尝试,为 XML Namespace Selector 创建了一个 jQuery 插件 jquery.xmlns.js。它试图支持以下代码。
$.xmlns["ex"] = "http://example.com";
$(doc).find("ex|quote").each(...);
第一行是对该插件的全局名称空间声明 — 由于底层 jQuery 机制的局限性。它的确用典型的 jQuery 用语为名称空间范围提供一个非全局块。 遗憾的是,我在使用这种扩展时成败参半。我希望它能够改变,并最终找到合适的方法进入 jQuery 。
一个更简单的插件
我最终选择的解决方案是创建一个简单插件,它不使用 jQuery 选择器做任何特殊工作,而是添加一个新的过滤器。您可以直接传递一个名称空间和本地名称到该过滤器,从而使结果集与节点匹配。请您按以下方法使用它:
$(xml).find('*').ns_filter('http://example.com', 'quote').each(function(){
.each(function() {
//process each node
});
ns_filter 是我写的特殊过滤器。执行一个单独的 find('*') 的需求看起来可能不优雅,更简单的变化可能是:
$(xml).find('quote').ns_filter('http://example.com').each(function(){
.each(function() {
//process each node
});
然而,这样做并不可行,因为您不能相信 jQuery 能够以名称空间中立(即作为本地名称选择器)的方式来处理查询,例如 find('quote')。我的过滤器实现将在下一节提供,作为安装 jQuery 来处理 XML 的一般系统的一部分。我在 Mac OS X Snow Leopard 操作系统下的 Firefox 3.5.5 和 Safari 4.0.4 ,以及 Windows® XP 操作系统最新的 Internet Explore 7 和 Internet Explorer 8 浏览器中对它进行了测试。
jQuery XML 工作台
名称空间问题只是以下事实的症状:说到底,jQuery 是一个 HTML 工具。我发现,使用 jQuery 处理 XML 最实用的方式就是为 XML 文档创建一个 HTML 工作台,通过可靠地跨浏览器方法引用脚本,然后建立需要的暂时性解决方案,例如针对 XML 名称空间问题的解决方案。您可以用工作台模式准备并测试您基于浏览器的 XML 处理的模式和技术,您甚至还可以把工作台作为基于浏览器的应用程序本身的基础。
清单 1 (quotes.html)是 HTML 使用工作台的简单例子。它能够动态地从 XML 文件加载引用。
清单 1 (quotes.html). 使用 jQuery XML 工作台的 HTML 例子
jQuery、ワークベンチ JavaScript、およびアプリケーション固有のスクリプトを自動的にロードするには、script 要素が必要です。 target_XML で使用される XML ファイルを識別するための link 要素も必要です。複数の XML ファイルを操作する必要がある場合は、ワークベンチのセットアップを簡単に拡張できます。リスト 2 (workbench.js) はワークベンチ スクリプトです。
リスト 2 (workbench.js)。jQuery XML Workbench JavaScript
/*
workbench.js
*/
// DOM の準備が完了すると呼び出される jQuery フック
$(document).ready(function() {
//ターゲットのXML ファイルの内容を取得(Ajax call)
var fileurl = $("link[rel='target_XML']").attr('href');
$.ajax({
url: fileurl,
) type: "GET",
dataType: "xml",
complete: xml_ready,
error: error_func
});
});
// Ajax呼び出しでエラーが発生した場合のコールバック
function error_func(result ) {
alert(result.responseText);
}
//ns_filter、(this).filter(function() の jQuery 拡張機能。{
var domnode =$(this)[0];
return (domnode.namespaceURI = =namespaceURI &&domnode.localName ==localName);
});
};
} )(jQuery);
リスト 3. (quotes.js) 動的見積ビューアのアプリケーション コード
quotes.js
*/function xml_ready(result){
var データ挿入対象領域がクリア
').each(function (){
var quote_text =$(this).text()
$('
リスト 4 (quotes1.xml) は引用リストの XML ファイルです。
リスト 4. (quotes1.xml) は引用リストの XML ファイルです
では、次の意味の x 接頭辞を使用していることに注意してください。理論的には、上記のプレフィックスベースのハックを試すこともできますが、そうすると壊れてしまいます。リスト 5 の引用ファイル (quotes2.xml) は、リスト 4 とまったく同じ名前空間であり、同じものです。正規の XML。
リスト 5. (quotes2.xml) 引用リスト
言葉には意味があり、名前には力がある
棒や石は私の骨を壊しますが、名前には決して傷つけられません。
知恵の始まりは、物事を正しい名前で呼ぶことです。
名前を聞くよりも顔を見る方が良いです。如果您替代 清单 1 中的 quotes2.xml,您将发现它还起作用,这是一个针对名称空间的重要测试。图 1 是 quotes.html 的浏览器显示。
图 1. 使用 jQuery XML 工作台展示的引用
Atom XML 的动态显示一旦您开始在 jQuery 中进行 XML 处理,您就能够处理更多有用的 XML 格式,包括 Web 提要格式,例如 RSS 和 Atom。在此部分我将使用 jQuery XML 工作台来显示来自一个 Web 页面上 Atom 提要的最新条目。清单 6 是 HTML 页面。
清单 6. (home.html)托管动态 XML 的 Web 页面
jQuery XML workbench
Caesar's home page
GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae,
aliam Aquitani, tertiam qui ipsorum lingua Celtae, nostra Galli
appellantur. Hi omnes lingua, institutis, legibus inter se differunt.
Gallos ab Aquitanis Garumna flumen, a Belgis Matrona et Sequana dividit.
Horum omnium fortissimi sunt Belgae, propterea quod a cultu atque
humanitate provinciae longissime absunt, minimeque ad eos mercatores saepe
commeant atque ea quae ad effeminandos animos pertinent important,
proximique sunt Germanis, qui trans Rhenum incolunt, quibuscum continenter
bellum gerunt. Qua de causa Helvetii quoque reliquos Gallos virtute
praecedunt, quod fere cotidianis proeliis cum Germanis contendunt, cum aut
suis finibus eos prohibent aut ipsi in eorum finibus bellum gerunt.
My Web feed
クリア单 7(atom1.xml)は参照の Atom ファイルです。 1.0" encoding="utf-8"?>
xml:lang="en" xml:base="http:/ /www.example.org">
http://www.example.org/myfeed
My Simple Feed
2005-07- 15T12:00:00Z
ウチェOgboji
http://www.example.org/entries/1
A simple blog entry
2005-07-14T12:00:00Z
<まとめ>これは 簡単なブログエントリーです概要>
http://www.example.org/entries/2
2005-07-15T12:00:00Z
<まとめ>これは、タイトルなしの簡単なブログエントリーです概要>
エントリ>
フィード>
クリア 8 は home.js であり、プラットフォームに追加されたアプリケーション プログラムのコードが含まれています。 *
home.js
*/
var ATOM_NS = 'http://www.w3.org/2005/Atom';
function xml_ready(result){var xml = result.responseXML;
//Make sure theデータを挿入する対象の領域はクリア$("#update-target").empty();
.ns_filter(ATOM_NS, 'link')
$(xml).find('*').ns_filter(ATOM_NS, 'entry').each(function(){
var title_elem = $(this).find('*').ns_filter(ATOM_NS, 'title').clone();
var link_text = $(this).find('[rel="alternate"]').attr('href');
link_text = $(this).find('*')
var summary_elem = $(this).find('*').ns_filter(ATOM_NS, 'summary').clone();
//欠落しているタイトルの場合を処理します
if (!title_elem.text()){
title_elem = '[No title]';
}
// rel='alternate'が省略されている場合を処理する
if (!link_text){.ns_filter(ATOM_NS, 'link')
.not('[rel]')
attr('href');
}//対象エリアを エントリ情報で更新
')
$('
.append(
$(' ')
.append(title_elem)
)
.append(' - ') .append(summary_elem.clone()).fadeIn('slow') //ボーナス アニメーション
.appendTo(' #update-target');
}); //close それぞれ(
}もう一度、このファイルにコメントしましたが、強調する価値のある点がいくつかあります。 Atom には許容可能な要素のバリエーションが多数あり、そのほとんどはオプションです。つまり、例外を処理する必要があります。一般的な例外として、必須リンクの rel="alternate" がオプションであることと、タイトルがオプションであることを 2 つ挙げます。ご覧のとおり、jQuery はこれらの状況に非常に柔軟に対応できるため、このような不規則な XML 形式でも処理できるはずです。場合によっては、構造を XML からメインドキュメント (ホストされた HTML) に直接コピーしました。これには十分な注意が必要です。 clone() メソッドを使用して、あるドキュメントから別のドキュメントにノードを接ぎ木しないようにしています。そうしないと、DOM 例外 WRONG_DOCUMENT_ERR が発行されます。さらに、追加されたコンテンツが徐々に表示から消えるように、jQuery メソッド fadeIn を使用しました。図2はhome.htmlのブラウザ表示です。
上記は、ブラウザーで XML を処理するために jQuery を使用しています。その他の関連記事については、PHP 中国語 Web サイト (www.php.cn) に注目してください。