Neither xsl:include nor xsl:import are used. A snippet of the XSLT is shown below. In IE 6 on WinXPSP2, the tag
name display is 'html' (and only because the web page is well-formed otherwise an error would occur). The
xsl:variable shows how I'm trying to use document(''). In practice the XSLT is constructed as a JavaScript string.
According to the rec, document("") refers to the root node
of the stylesheet so this an MSXML bug. Just to make sure
this is not my bad, have you tried scripting the
transformation with native MSXML APIs (i.e. without sarissa)?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes, I originally developed on IE and ported it to Sarissa. The
original IE code was xmlDoc.transformNode(xsltDoc), so it didn't use
createProcessor. It was a fairly easy port and most of it works fine
on both IE and FF. You've done a good job making it cross-browser. I
hope there is just some context property that needs to be set in the
transform object that is incorrect for both browsers. In .NET a
UrlResolver required when the XSLT is a string instead of a file.
The problem, although different, also happens with Mozilla FireFox.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The XSLT is originally a string, so I don't think xml:base will help. And neither Firefox nor IE works correctly,
so it wouldn't be just something with how IE is handled.
Shown here is the code I use to transform:
var xmlDoc = Sarissa.getDomDocument();
xmlDoc.async = false;
xmlDoc = (new DOMParser()).parseFromString(xml, "text/xml");
var xsltDoc = Sarissa.getDomDocument();
xsltDoc.async = false;
xsltDoc = (new DOMParser()).parseFromString(xslt, "text/xml");
var processor = new XSLTProcessor();
processor.importStylesheet(xsltDoc);
var newDoc = processor.transformToDocument(xmlDoc);
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The AllowDocumentFunction property is now set for MSXML 6.0, but the original problem remains. The document('') function does not reference the XSLT document itself when the XSLT is a string rather than a URL. IE references the web page. FireFox references the XML document.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hmm. This comes to choosing between the ability to get/set parameters ( i need to re-parse the stylesheet for the threaded doc) and keeping the url. That last property is read only i think.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Actually, in my case, the XSLT is originally a string, not a URL, so it's not a matter of keeping the URL.
I was thinking, in those cases where the XSLT is a URL, to have a separate method to load the XSLT URL using the FreeThreadedDOMDocument object to avoid having to load the XSLT twice.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In working with both Microsoft and Mozilla, they have acknowledged the problem. There is some debate as to whether document('') should refer to the web page when the XSLT is a string because the string does not have a URI and therefore it defaults back to the web page. Since it is important for an XSLT to reference itself (and not the web page it might be in), IMHO, it document('') should consistently reference the XSLT regardless of whether the XSLT is a string or URL.
However, in regard to Sarissa, the problem is broadly exposed by serializing the XSLT as a string and loading it into FreeThreadedDOMDocument. I thought of adding a Sarissa.getXsltDocument method that would use FreeThreadedDOMDocument and therefore not need to reload the XSLT in XSLTProcessor.prototype.importStylesheet.
Any thoughts?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
As a workaround, Jonas Sicking writes, "One way of doing so would be to use .setParameter to pass the DOM of the stylesheet as a parameter and then refer to the stylesheet through that parameter." - http://groups.google.com/group/mozilla.dev.tech.xslt on thread "problem self-referencing using document('') to reference parameters" dated Apr 25, 6:17 pm
If I come up with a working solution, I'll post it here. I don't think there is one for Mozilla, but I'll try creating a separate method to create an XsltDocument using FreeThreadedDOMDocument in IE to at least reduce probably of encountering the problem.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
This seems to work. There is a new method getXsltDocument, similar to getDomDocument, but for XSLTs. Also affected is .importStylesheet (for IE). There are three places where getDomDocument is defined other than for IE that need the following line:
Sarissa.getXsltDocument = Sarissa.getDomDocument;
I've tested on IE 7/Windows and FireFox 2.0/Windows.
Sarissa.getXsltDocument = function(sUri, sName){
if(!_SARISSA_THREADEDDOM_PROGID){
_SARISSA_THREADEDDOM_PROGID = Sarissa.pickRecentProgID(["MSXML2.FreeThreadedDOMDocument.6.0", "MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.5.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
};
var oDoc = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID);
Sarissa.setXpathNamespaces(oDoc, "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
oDoc.resolveExternals = true; // MSXML 2.0 and later
if ("MSXML2.FreeThreadedDOMDocument.6.0" == _SARISSA_THREADEDDOM_PROGID) {
oDoc.setProperty("AllowDocumentFunction", true); // This property is supported in MSXML 3.0 SP4, 4.0 SP2, 5.0, and 6.0. The default value is true for 3.0, 4.0, and 5.0. The default value is false for 6.0.
oDoc.setProperty("AllowXsltScript", true); // This property is supported in MSXML 3.0 SP8, 5.0 SP2, and 6.0. The default value is true for 3.0 and 5.0. The default value is false for 6.0.
oDoc.setProperty("ProhibitDTD", false); // This property is supported in MSXML 3.0 SP5, 4.0 SP3, 5.0 SP2, and 6.0. The default value is false for 3.0, 4.0, and 5.0. The default value is true for 6.0.
}
// if a root tag name was provided, we need to load it in the DOM object
if (sName){
// create an artifical namespace prefix
// or reuse existing prefix if applicable
var prefix = "";
if(sUri){
if(sName.indexOf(":") > 1){
prefix = sName.substring(0, sName.indexOf(":"));
sName = sName.substring(sName.indexOf(":")+1);
}else{
prefix = "a" + (_sarissa_iNsCounter++);
};
};
// use namespaces if a namespace URI exists
if(sUri){
oDoc.loadXML('<' + prefix+':'+sName + " xmlns:" + prefix + "=\"" + sUri + "\"" + " />");
} else {
oDoc.loadXML('<' + sName + " />");
};
};
return oDoc;
};
XSLTProcessor.prototype.importStylesheet = function(xslDoc){
if(!_SARISSA_THREADEDDOM_PROGID){
_SARISSA_THREADEDDOM_PROGID = Sarissa.pickRecentProgID(["MSXML2.FreeThreadedDOMDocument.6.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
};
xslDoc.setProperty("SelectionLanguage", "XPath");
xslDoc.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
// convert stylesheet to free threaded
var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID);
// make included/imported stylesheets work if exist and xsl was originally loaded from url
if(xslDoc.url && xslDoc.selectSingleNode("//xsl:*[local-name() = 'import' or local-name() = 'include']") != null){
converted.async = false;
if (_SARISSA_THREADEDDOM_PROGID == "MSXML2.FreeThreadedDOMDocument.6.0") {
converted.setProperty("AllowDocumentFunction", true);
converted.resolveExternals = true;
}
converted.load(xslDoc.url);
} else {
converted.loadXML(xslDoc.xml);
};
converted.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
var output = converted.selectSingleNode("//xsl:output");
this.outputMethod = output ? output.getAttribute("method") : "html";
this.template.stylesheet = converted;
this.processor = this.template.createProcessor();
// for getParameter and clearParameters
this.paramsSet = new Array();
};
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Logged In: YES
user_id=542984
hey Doug, are you using xsl:include or xsl:import?
Logged In: YES
user_id=1545119
Neither xsl:include nor xsl:import are used. A snippet of the XSLT is shown below. In IE 6 on WinXPSP2, the tag
name display is 'html' (and only because the web page is well-formed otherwise an error would occur). The
xsl:variable shows how I'm trying to use document(''). In practice the XSLT is constructed as a JavaScript string.
Thank you for your response.
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="ektdesign"
xmlns:ektdesign="urn:ektdesign">
<xsl:output method="xml" version="1.0" indent="yes" omit-xml-declaration="yes"/>
<ektdesign:datalist>
<option>test</option>
</ektdesign:datalist>
<xsl:variable name="oldDataList" select="document('')/xsl:stylesheet/ektdesign:datalist"/>
<xsl:template match="select">
<select>
<option><xsl:value-of select="name(document('')/*[1])" /></option>
</select>
</xsl:template>
:
</xsl:stylesheet>
Logged In: YES
user_id=542984
According to the rec, document("") refers to the root node
of the stylesheet so this an MSXML bug. Just to make sure
this is not my bad, have you tried scripting the
transformation with native MSXML APIs (i.e. without sarissa)?
Logged In: YES
user_id=1545119
Yes, I originally developed on IE and ported it to Sarissa. The
original IE code was xmlDoc.transformNode(xsltDoc), so it didn't use
createProcessor. It was a fairly easy port and most of it works fine
on both IE and FF. You've done a good job making it cross-browser. I
hope there is just some context property that needs to be set in the
transform object that is incorrect for both browsers. In .NET a
UrlResolver required when the XSLT is a string instead of a file.
The problem, although different, also happens with Mozilla FireFox.
Logged In: YES
user_id=542984
I think i know what is wrong. In IE, i serialise the XSLT to
make it a freethreaded/template combo, so it misses the
context info.
Maybe if the XSLT loaded had an xml:base attribute [1]?
[1] http://www.w3.org/TR/xmlbase/#syntax
Logged In: YES
user_id=1545119
The XSLT is originally a string, so I don't think xml:base will help. And neither Firefox nor IE works correctly,
so it wouldn't be just something with how IE is handled.
Shown here is the code I use to transform:
var xmlDoc = Sarissa.getDomDocument();
xmlDoc.async = false;
xmlDoc = (new DOMParser()).parseFromString(xml, "text/xml");
var xsltDoc = Sarissa.getDomDocument();
xsltDoc.async = false;
xsltDoc = (new DOMParser()).parseFromString(xslt, "text/xml");
var processor = new XSLTProcessor();
processor.importStylesheet(xsltDoc);
var newDoc = processor.transformToDocument(xmlDoc);
Logged In: NO
If this is MSXML 6.0 the document() function now works on CVS.
Logged In: YES
user_id=1545119
Originator: YES
The AllowDocumentFunction property is now set for MSXML 6.0, but the original problem remains. The document('') function does not reference the XSLT document itself when the XSLT is a string rather than a URL. IE references the web page. FireFox references the XML document.
Logged In: NO
Hmm. This comes to choosing between the ability to get/set parameters ( i need to re-parse the stylesheet for the threaded doc) and keeping the url. That last property is read only i think.
Logged In: YES
user_id=1545119
Originator: YES
Actually, in my case, the XSLT is originally a string, not a URL, so it's not a matter of keeping the URL.
I was thinking, in those cases where the XSLT is a URL, to have a separate method to load the XSLT URL using the FreeThreadedDOMDocument object to avoid having to load the XSLT twice.
Logged In: YES
user_id=1545119
Originator: YES
In working with both Microsoft and Mozilla, they have acknowledged the problem. There is some debate as to whether document('') should refer to the web page when the XSLT is a string because the string does not have a URI and therefore it defaults back to the web page. Since it is important for an XSLT to reference itself (and not the web page it might be in), IMHO, it document('') should consistently reference the XSLT regardless of whether the XSLT is a string or URL.
However, in regard to Sarissa, the problem is broadly exposed by serializing the XSLT as a string and loading it into FreeThreadedDOMDocument. I thought of adding a Sarissa.getXsltDocument method that would use FreeThreadedDOMDocument and therefore not need to reload the XSLT in XSLTProcessor.prototype.importStylesheet.
Any thoughts?
Logged In: NO
I'm a bit dizzy right now, how can we make this work for both IE and browsers implementing Mozilla's XSLTProcessor?
Many thanks,
Manos
Logged In: YES
user_id=1545119
Originator: YES
As a workaround, Jonas Sicking writes, "One way of doing so would be to use .setParameter to pass the DOM of the stylesheet as a parameter and then refer to the stylesheet through that parameter." - http://groups.google.com/group/mozilla.dev.tech.xslt on thread "problem self-referencing using document('') to reference parameters" dated Apr 25, 6:17 pm
If I come up with a working solution, I'll post it here. I don't think there is one for Mozilla, but I'll try creating a separate method to create an XsltDocument using FreeThreadedDOMDocument in IE to at least reduce probably of encountering the problem.
Logged In: YES
user_id=1545119
Originator: YES
This seems to work. There is a new method getXsltDocument, similar to getDomDocument, but for XSLTs. Also affected is .importStylesheet (for IE). There are three places where getDomDocument is defined other than for IE that need the following line:
Sarissa.getXsltDocument = Sarissa.getDomDocument;
I've tested on IE 7/Windows and FireFox 2.0/Windows.
Sarissa.getXsltDocument = function(sUri, sName){
if(!_SARISSA_THREADEDDOM_PROGID){
_SARISSA_THREADEDDOM_PROGID = Sarissa.pickRecentProgID(["MSXML2.FreeThreadedDOMDocument.6.0", "MSXML2.FreeThreadedDOMDocument.4.0", "MSXML2.FreeThreadedDOMDocument.5.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
};
var oDoc = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID);
Sarissa.setXpathNamespaces(oDoc, "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
oDoc.resolveExternals = true; // MSXML 2.0 and later
if ("MSXML2.FreeThreadedDOMDocument.6.0" == _SARISSA_THREADEDDOM_PROGID) {
oDoc.setProperty("AllowDocumentFunction", true); // This property is supported in MSXML 3.0 SP4, 4.0 SP2, 5.0, and 6.0. The default value is true for 3.0, 4.0, and 5.0. The default value is false for 6.0.
oDoc.setProperty("AllowXsltScript", true); // This property is supported in MSXML 3.0 SP8, 5.0 SP2, and 6.0. The default value is true for 3.0 and 5.0. The default value is false for 6.0.
oDoc.setProperty("ProhibitDTD", false); // This property is supported in MSXML 3.0 SP5, 4.0 SP3, 5.0 SP2, and 6.0. The default value is false for 3.0, 4.0, and 5.0. The default value is true for 6.0.
}
// if a root tag name was provided, we need to load it in the DOM object
if (sName){
// create an artifical namespace prefix
// or reuse existing prefix if applicable
var prefix = "";
if(sUri){
if(sName.indexOf(":") > 1){
prefix = sName.substring(0, sName.indexOf(":"));
sName = sName.substring(sName.indexOf(":")+1);
}else{
prefix = "a" + (_sarissa_iNsCounter++);
};
};
// use namespaces if a namespace URI exists
if(sUri){
oDoc.loadXML('<' + prefix+':'+sName + " xmlns:" + prefix + "=\"" + sUri + "\"" + " />");
} else {
oDoc.loadXML('<' + sName + " />");
};
};
return oDoc;
};
XSLTProcessor.prototype.importStylesheet = function(xslDoc){
if(!_SARISSA_THREADEDDOM_PROGID){
_SARISSA_THREADEDDOM_PROGID = Sarissa.pickRecentProgID(["MSXML2.FreeThreadedDOMDocument.6.0", "MSXML2.FreeThreadedDOMDocument.3.0"]);
};
xslDoc.setProperty("SelectionLanguage", "XPath");
xslDoc.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
// convert stylesheet to free threaded
var converted = new ActiveXObject(_SARISSA_THREADEDDOM_PROGID);
// make included/imported stylesheets work if exist and xsl was originally loaded from url
if(xslDoc.url && xslDoc.selectSingleNode("//xsl:*[local-name() = 'import' or local-name() = 'include']") != null){
converted.async = false;
if (_SARISSA_THREADEDDOM_PROGID == "MSXML2.FreeThreadedDOMDocument.6.0") {
converted.setProperty("AllowDocumentFunction", true);
converted.resolveExternals = true;
}
converted.load(xslDoc.url);
} else {
converted.loadXML(xslDoc.xml);
};
converted.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
var output = converted.selectSingleNode("//xsl:output");
this.outputMethod = output ? output.getAttribute("method") : "html";
this.template.stylesheet = converted;
this.processor = this.template.createProcessor();
// for getParameter and clearParameters
this.paramsSet = new Array();
};