XInclude - MDN Web Docs Glossary: Definitions of Web-related terms 编辑
XML Inclusions (XInclude) is a W3C Recommendation to allow inclusion of XML more different sources in a more convenient fashion than XML external entities. When used in conjunction with XPointer (Firefox supports a subset of it, and is used in the code sample below), XInclude can also target just specific portions of a document for inclusion. Firefox does not support it natively, but the following function aims to allow its use with documents passed into it.
Code sample
The following code aims to let <xi:include> and <xi:fallback> tags (the two elements in the language) with all of the attributes of <xi:include> be included in an XML document so as to be resolvable into a single XML document.
(Note that this has not been thoroughly tested for all circumstances and may not necessarily reflect the standard behavior completely.)
Note also that if you wish to allow xml:base, you will need the xml:base function, and the line beginning var href = ...
should become:
var href = getXmlBaseLink (/* XLink sans xml:base */ xinclude.getAttribute('href'), /* Element to query from */ xinclude);
function resolveXIncludes(docu) {
// http://www.w3.org/TR/xinclude/#xml-included-items
var xincludes = docu.getElementsByTagNameNS('http://www.w3.org/2001/XInclude', 'include');
if (xincludes) {
for (i=0; i < xincludes.length; i++) {
var xinclude = xincludes[i];
var href = xinclude.getAttribute('href');
var parse = xinclude.getAttribute('parse');
var xpointer = xinclude.getAttribute('xpointer');
var encoding = xinclude.getAttribute('encoding'); // e.g., UTF-8 // "text/xml or application/xml or matches text/*+xml or application/*+xml" before encoding (then UTF-8)
var accept = xinclude.getAttribute('accept'); // header "Accept: "+x
var acceptLanguage = xinclude.getAttribute('accept-language'); // "Accept-Language: "+x
var xiFallback = xinclude.getElementsByTagNameNS('http://www.w3.org/2001/XInclude', 'fallback')[0]; // Only one such child is allowed
if (href === '' || href === null) { // Points to same document if empty (null is equivalent to empty string)
href = null; // Set for uniformity in testing below
if (parse === 'xml' && xpointer === null) {
alert('There must be an XPointer attribute present if "href" is empty an parse is "xml"');
return false;
}
}
else if (href.match(/#$/, '') || href.match(/^#/, '')) {
alert('Fragment identifiers are disallowed in an XInclude "href" attribute');
return false;
}
var j;
var xincludeParent = xinclude.parentNode;
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserRead'); // Necessary with file:///-located files trying to reach external sites
if (href !== null) {
var response, responseType;
var request = new XMLHttpRequest();
request.open('GET', href, false);
request.setRequestHeader('If-Modified-Since', 'Thu, 1 Jan 1970 00:00:00 GMT');
request.setRequestHeader('Cache-Control', 'no-cache');
if (accept) {
request.setRequestHeader('Accept', accept);
}
if (acceptLanguage) {
request.setRequestHeader('Accept-Language', acceptLanguage);
}
switch (parse) {
case 'text':
// Priority should be on media type:
var contentType = request.getResponseHeader('Content-Type');
//text/xml; charset="utf-8" // Send to get headers first?
// Fix: We test for file extensions as well in case file:// doesn't return content type (as seems to be the case); can some other tool be uesd in FF (or IE) to detect encoding of local file? Probably just need BOM test since other encodings must be specified
var patternXML = /\.(svg|xml|xul|rdf|xhtml)$/;
if ((contentType && contentType.match(/[text|application]\/(.*)\+?xml/)) || (href.indexOf('file://') === 0 && href.match(patternXML))) {
/* Grab the response as text (see below for that routine) and then find encoding within*/
var encName = '([A-Za-z][A-Za-z0-9._-]*)';
var pattern = new RegExp('^<\\?xml\\s+.*encoding\\s*=\\s*([\'"])'+encName+'\\1.*\\?>'); // Check document if not?
// Let the request be processed below
}
else {
if (encoding === '' || encoding === null) { // Encoding has no effect on XML
encoding = 'utf-8';
}
request.overrideMimeType('text/plain; charset='+encoding); //'x-user-defined'
}
responseType = 'responseText';
break;
case null:
case 'xml':
responseType = 'responseXML';
break;
default:
alert('XInclude element contains an invalid "parse" attribute value');
return false;
break;
}
request.send(null);
if((request.status === 200 || request.status === 0) && request[responseType] !== null) {
response = request[responseType];
if (responseType === 'responseXML') {
// apply xpointer (only xpath1() subset is supported)
var responseNodes;
if (xpointer) {
var xpathResult = response.evaluate(
xpointer,
response,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
var a = [];
for(var k = 0; k < xpathResult.snapshotLength; k++) {
a[k] = xpathResult.snapshotItem(k);
}
responseNodes = a;
}
else { // Otherwise, the response must be a single well-formed document response
responseNodes = [response.documentElement]; // Put in array so can be treated the same way as the above
}
// PREPEND ANY NODE(S) (AS XML) THEN REMOVE XINCLUDE
for (j=0; j < responseNodes.length ; j++) {
xincludeParent.insertBefore(responseNodes[j], xinclude);
}
xincludeParent.removeChild(xinclude);
}
else if (responseType === 'responseText') {
if (encName) {
var encodingType = response.match(pattern);
if (encodingType) {
encodingType = encodingType[2];
}
else {
encodingType = 'utf-8';
}
// Need to make a whole new request apparently since cannot convert the encoding after receiving it (to know what the encoding was)
var request2 = new XMLHttpRequest();
request2.overrideMimeType('text/plain; charset='+encodingType);
request2.open('GET', href, false);
request2.setRequestHeader('If-Modified-Since', 'Thu, 1 Jan 1970 00:00:00 GMT');
request2.setRequestHeader('Cache-Control', 'no-cache');
request2.send(null);
response = request2[responseType]; // Update the response for processing
}
// REPLACE XINCLUDE WITH THE RESPONSE AS TEXT
var textNode = docu.createTextNode(response); xincludeParent.replaceChild(textNode, xinclude);
}
// replace xinclude in doc with response now (as plain text or XML)
}
}
}
catch (e) { // Use xi:fallback if XInclude retrieval above failed
var xiFallbackChildren = xiFallback.childNodes;
// PREPEND ANY NODE(S) THEN REMOVE XINCLUDE
for (j=0; j < xiFallbackChildren.length ; j++) {
xincludeParent.insertBefore(xiFallbackChildren[j], xinclude);
}
xincludeParent.removeChild(xinclude);
}
}
}
return docu;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论