display.php-n=xml.js&f=21-xml.js.htm

来自「javascript 5 随书源码 javascript」· HTM 代码 · 共 645 行 · 第 1/2 页

HTM
645
字号
XML.Transformer.prototype.transform = function(node, element) {    // If element is specified by id, look it up    if (typeof element == "string") element = document.getElementById(element);    if (this.processor) {        // If we've created an XSLTProcessor (i.e. we're in Mozilla) use it.        // Transform the node into a DOM DocumentFragment        var fragment = this.processor.transformToFragment(node, document);        // Erase the existing content of element        element.innerHTML = "";        // And insert the transformed nodes        element.appendChild(fragment);    }    else if ("transformNode" in node) {        // If the node has a transformNode() function (in IE), use that.        // Note that transformNode() returns a string.        element.innerHTML = node.transformNode(this.stylesheet);    }    else {        // Otherwise, we're out of luck        throw "XSLT is not supported in this browser";    }};/** * This is an XSLT utility function that is useful when a stylesheet is * used only once. */XML.transform = function(xmldoc, stylesheet, element) {    var transformer = new XML.Transformer(stylesheet);    transformer.transform(xmldoc, element);}/** * XML.XPathExpression is a class that encapsulates an XPath query and its * associated namespace prefix-to-URL mapping.  Once an XML.XPathExpression * object has been created, it can be evaluated one or more times (in one * or more contexts) using the getNode() or getNodes() methods. * * The first argument to this constructor is the text of the XPath expression. *  * If the expression includes any XML namespaces, the second argument must * be a JavaScript object that maps namespace prefixes to the URLs that define * those namespaces.  The properties of this object are the prefixes, and * the values of those properties are the URLs. */XML.XPathExpression = function(xpathText, namespaces) {    this.xpathText = xpathText;    // Save the text of the expression    this.namespaces = namespaces;  // And the namespace mapping    if (document.createExpression) {        // If we're in a W3C-compliant browser, use the W3C API        // to compile the text of the XPath query        this.xpathExpr =             document.createExpression(xpathText,                                       // This function is passed a                                       // namespace prefix and returns the URL.                                      function(prefix) {                                          return namespaces[prefix];                                      });    }    else {        // Otherwise, we assume for now that we're in IE and convert the        // namespaces object into the textual form that IE requires.        this.namespaceString = "";        if (namespaces != null) {            for(var prefix in namespaces) {                // Add a space if there is already something there                if (this.namespaceString) this.namespaceString += ' ';                // And add the namespace                this.namespaceString += 'xmlns:' + prefix + '="' +                    namespaces[prefix] + '"';            }        }    }};/** * This is the getNodes() method of XML.XPathExpression.  It evaluates the * XPath expression in the specified context.  The context argument should * be a Document or Element object.  The return value is an array  * or array-like object containing the nodes that match the expression. */XML.XPathExpression.prototype.getNodes = function(context) {    if (this.xpathExpr) {        // If we are in a W3C-compliant browser, we compiled the        // expression in the constructor.  We now evaluate that compiled        // expression in the specified context        var result =            this.xpathExpr.evaluate(context,                                     // This is the result type we want                                    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,                                    null);        // Copy the results we get into an array.        var a = new Array(result.snapshotLength);        for(var i = 0; i &lt; result.snapshotLength; i++) {            a[i] = result.snapshotItem(i);        }        return a;    }    else {        // If we are not in a W3C-compliant browser, attempt to evaluate        // the expression using the IE API.        try {            // We need the Document object to specify namespaces            var doc = context.ownerDocument;            // If the context doesn't have ownerDocument, it is the Document            if (doc == null) doc = context;            // This is IE-specific magic to specify prefix-to-URL mapping            doc.setProperty("SelectionLanguage", "XPath");            doc.setProperty("SelectionNamespaces", this.namespaceString);            // In IE, the context must be an Element not a Document,             // so if context is a document, use documentElement instead            if (context == doc) context = doc.documentElement;            // Now use the IE method selectNodes() to evaluate the expression            return context.selectNodes(this.xpathText);        }        catch(e) {            // If the IE API doesn't work, we just give up            throw "XPath not supported by this browser.";        }    }}/** * This is the getNode() method of XML.XPathExpression.  It evaluates the * XPath expression in the specified context and returns a single matching * node (or null if no node matches).  If more than one node matches, * this method returns the first one in the document. * The implementation differs from getNodes() only in the return type. */XML.XPathExpression.prototype.getNode = function(context) {    if (this.xpathExpr) {        var result =            this.xpathExpr.evaluate(context,                                     // We just want the first match                                    XPathResult.FIRST_ORDERED_NODE_TYPE,                                    null);        return result.singleNodeValue;    }    else {        try {            var doc = context.ownerDocument;            if (doc == null) doc = context;            doc.setProperty("SelectionLanguage", "XPath");            doc.setProperty("SelectionNamespaces", this.namespaceString);            if (context == doc) context = doc.documentElement;            // In IE call selectSingleNode instead of selectNodes            return context.selectSingleNode(this.xpathText);        }        catch(e) {            throw "XPath not supported by this browser.";        }    }};// A utility to create an XML.XPathExpression and call getNodes() on itXML.getNodes = function(context, xpathExpr, namespaces) {    return (new XML.XPathExpression(xpathExpr, namespaces)).getNodes(context);};// A utility to create an XML.XPathExpression and call getNode() on itXML.getNode  = function(context, xpathExpr, namespaces) {    return (new XML.XPathExpression(xpathExpr, namespaces)).getNode(context);};/** * Serialize an XML Document or Element and return it as a string. */XML.serialize = function(node) {    if (typeof XMLSerializer != "undefined")        return (new XMLSerializer()).serializeToString(node);    else if (node.xml) return node.xml;    else throw "XML.serialize is not supported or can't serialize " + node;};/* * Expand any templates at or beneath element e. * If any of the templates use XPath expressions with namespaces, pass * a prefix-to-URL mapping as the second argument as with XML.XPathExpression() *  * If e is not supplied, document.body is used instead.  A common  * use case is to call this function with no arguments in response to an * onload event handler.  This automatically expands all templates. */XML.expandTemplates = function(e, namespaces) {    // Fix up arguments a bit.    if (!e) e = document.body;    else if (typeof e == "string") e = document.getElementById(e);    if (!namespaces) namespaces = null; // undefined does not work    // An HTML element is a template if it has a "datasource" attribute.    // Recursively find and expand all templates.  Note that we don't    // allow templates within templates.    if (e.getAttribute("datasource")) {        // If it is a template, expand it.        XML.expandTemplate(e, namespaces);    }    else {        // Otherwise, recurse on each of the children.  We make a static         // copy of the children first so that expanding a template doesn't        // mess up our iteration.        var kids = []; // To hold copy of child elements        for(var i = 0; i &lt; e.childNodes.length; i++) {            var c = e.childNodes[i];            if (c.nodeType == 1) kids.push(e.childNodes[i]);        }                // Now recurse on each child element        for(var i = 0; i &lt; kids.length; i++)            XML.expandTemplates(kids[i], namespaces);    }};/** * Expand a single specified template. * If the XPath expressions in the template use namespaces, the second * argument must specify a prefix-to-URL mapping */XML.expandTemplate = function(template, namespaces) {    if (typeof template=="string") template=document.getElementById(template);    if (!namespaces) namespaces = null; // Undefined does not work    // The first thing we need to know about a template is where the     // data comes from.      var datasource = template.getAttribute("datasource");    // If the datasource attribute begins with '#', it is the name of    // an XML data island.  Otherwise, it is the URL of an external XML file    var datadoc;    if (datasource.charAt(0) == '#')   // Get data island        datadoc = XML.getDataIsland(datasource.substring(1));    else                               // Or load external document        datadoc = XML.load(datasource);    // Now figure out which nodes in the datasource will be used to     // provide the data.  If the template has a foreach attribute,    // we use it as an XPath expression to get a list of nodes.  Otherwise    // we use all child elements of the document element    var datanodes;    var foreach = template.getAttribute("foreach");    if (foreach) datanodes = XML.getNodes(datadoc, foreach, namespaces);    else {        // If there is no "foreach" attribute, use the element        // children of the documentElement        datanodes = [];        for(var c=datadoc.documentElement.firstChild; c!=null; c=c.nextSibling)            if (c.nodeType == 1) datanodes.push(c);    }    // Remove the template element from its parent,    // but remember the parent, and also the nextSibling of the template.    var container = template.parentNode;    var insertionPoint = template.nextSibling;    template = container.removeChild(template);    // For each element of the datanodes array, we'll insert a copy of    // the template back into the container.  Before doing this, though, we    // expand any child in the copy that has a "data" attribute.    for(var i = 0; i &lt; datanodes.length; i++) {        var copy = template.cloneNode(true);           // Copy template        expand(copy, datanodes[i], namespaces);        // Expand copy        container.insertBefore(copy, insertionPoint);  // Insert copy    }    // This nested function finds any child elements of e that have a data    // attribute.  It treats that attribute as an XPath expression and    // evaluates it in the context of datanode.  It takes the text value of    // the XPath result and makes it the content of the HTML node being    // expanded.  All other content is deleted    function expand(e, datanode, namespaces) {        for(var c = e.firstChild; c != null; c = c.nextSibling) {            if (c.nodeType != 1) continue;  // elements only            var dataexpr = c.getAttribute("data");            if (dataexpr) {                // Evaluate XPath expression in context                var n = XML.getNode(datanode, dataexpr, namespaces);                // Delete any content of the element                c.innerHTML = "";                // And insert the text content of the XPath result                c.appendChild(document.createTextNode(getText(n)));            }            // If we don't expand the element, recurse on it.            else expand(c, datanode, namespaces);        }    }    // This nested function extracts the text from a DOM node, recursing    // if necessary    function getText(n) {        switch(n.nodeType) {        case 1: /* element */            var s = "";            for(var c = n.firstChild; c != null; c = c.nextSibling)                s += getText(c);            return s;        case 2: /* attribute*/        case 3: /* text */        case 4: /* cdata */            return n.nodeValue;        default:             return "";        }    }    };</pre><div class="lefttitle" style="padding:0px; text-align: right"><a href="index.html" tppabs="http://www.davidflanagan.com/javascript5/index.html">Table of Examples</a></div><p><script type="text/javascript">amazon_ad_tag="davidflanagancom"; amazon_ad_width="300"; amazon_ad_height="250"; amazon_ad_logo="hide";</script><script type="text/javascript" src="../../www.assoc-amazon.com/s/ads.js" tppabs="http://www.assoc-amazon.com/s/ads.js"></script></div></body></html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?