mozilla
Your Search Results

    xml:base support in old browsers

    Before using this code, check if your browser has native support for Node.baseURI.

    These two functions aim to allow some support for xml:base.

    Note however, that this code is not based on a thorough examination of the specs related to forming base URIs and could well have a number of errors. However, it is working in some of the cases tested.

    var scheme = /(\w(\w|\d|\+|\- |\ .)*)\:\/\//;
    function getXmlBaseLink (xlink, thisitem) {
    	var xmlbase = '';
    	if (!xlink.match(scheme)) { // Only check for XML Base if there is no protocol // tests for 'scheme' per http://www.ietf.org/rfc/rfc2396.txt'
    		xmlbase = getXmlBase (thisitem); 
    		if (!xmlbase.match(/\/$/) && !xlink.match(/\/$/)) { // If no preceding slash on XLink or trailing slash on xml:base, add one in between
    			xmlbase += '/';
    		}
    		else if (xmlbase.match(/\/$/) && xlink.match(/\/$/)) {
    			xmlbase = xmlbase.substring(0, xmlbase.length-2); // Strip off last slash to join with XLink path with slash
    		}
    //                        alert(xmlbase + '::' + xlink);
    	}
    
    	var link = xmlbase + xlink;
    	if (!link.match(scheme)) { // If there is no domain, we'll need to use the current domain
    		var loc = window.location;
    		if (link.indexOf('/') === 0 ) { // If link is an absolute URL, it should be from the host only
    			link = loc.protocol + '//' + loc.host + link;
    		}
    		else { // If link is relative, it should be from full path, minus the file
    			var dirpath = loc.pathname.substring(0, loc.pathname.lastIndexOf('/')-1);
    			if (link.lastIndexOf('/') !== link.length-1) {
    				link += '/';
    			}
    			link = loc.protocol + '//' + loc.host + dirpath + link;
    		}
    	}
    
    	return link;
    }
    function getXmlBase (thisitem) {
    	// Fix: Need to keep going up the chain if still a relative URL!!!!!
    	// var ns = 'http://www.w3.org/XML/1998/namespace';
    	var att, protocolPos;
    	var xmlbase = '';
    	var abs = false;
    	// Avoid loop if node is not present
    	if (!thisitem || !thisitem.nodeName) {
    		return xmlbase;
    	}
    	// CHECK PRESENT ELEMENT AND HIGHER UP FOR XML:BASE
    	// Now check for the next matching local name up in the hierarchy (until the document root)
    	while (thisitem.nodeName !== '#document' && thisitem.nodeName !== '#document-fragment')  {
    		att = thisitem.getAttribute('xml:base'); // xml: namespaces MUST use 'xml' prefix
    		if (att) {
    			protocolPos = att.indexOf('//');
    			var protocolMatch = att.match(scheme);
    			if (protocolMatch) { // if has protocol, can stop
    				if (abs) {
    					var skipfile = (att.indexOf('///') === protocolPos) ? 3 : 2; // If the file protocol has an extra slashe, prepare to also skip it in the separator search
    					var att2 = att.indexOf('/', protocolPos+skipfile); // Find first path separator ('/') after protocol
    					if (att2 !== -1) {
    						att = att.substring(0, att2 - 1); // Don't want any trailing slash, as the absolute path to be added already has one
    					}
    				}
    				else if (!att.match(/\/$/)) { // If no trailing slash, add one, since it is being attached to a relative path
    					att += '/';
    				}
    				xmlbase = att + xmlbase; // If previous path was not absolute, resolve against the full URI here'
    				break;
    			}
    			else if (att.indexOf('/') === 0) { // if absolute (/), need to prepare for next time to strip out after slash
    				xmlbase = att + xmlbase;
    				abs = true; // Once the protocol is found on the next round, make sure any extra path is ignored
    			}
    			else { // if relative, just add it
    				xmlbase = att + xmlbase;
    			}
    		}
    		thisitem = thisitem.parentNode;
    	}
    	//return (xmlbase === '') ? null : xmlbase;
    	return xmlbase;
    }

    Document Tags and Contributors

    Tags: 
    Contributors to this page: wbamberg, Nickolay, Brettz9
    Last updated by: wbamberg,
    Hide Sidebar