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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:56 次

字数:10855

最后编辑:7年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文