Если ваш XSLT использует xsl:include
, вы можете получить странные необъяснимые ошибки, но всегда с тем же конечным результатом: ваше преобразование не выполнено.
Смотрите этот отчет об ошибках хрома и, пожалуйста, поддержите его!
http://code.google.com/p/chromium/issues/detail?id=8441
Ошибка на самом деле в webkit. Для получения дополнительной информации вот другая ссылка, которая более подробно объясняет, почему она не работает.
Единственный способ обойти это - предварительно обработать таблицу стилей, чтобы она внедрила включенные таблицы стилей. Именно это сделает для вас кроссбраузерная библиотека XSLT, такая как Sarissa, автоматически.
Если вы ищете решение jQuery:
http://plugins.jquery.com/project/Transform/ - кросс-браузерный XSL-плагин. Я успешно использовал это, чтобы заставить xsl:include
работать в прошлом без особых хлопот. Вам не нужно переписывать ваш xsl, этот плагин предварительно обработает их для вас. Определенно стоит посмотреть, так как он более легкий, чем Сарисса.
UPDATE:
<html>
<head>
<script language="javascript" src="jquery-1.3.2.min.js"></script>
<script language="javascript" src="jquery.transform.js"></script>
<script type="text/javascript">
function loadXML(file)
{
var xmlDoc = null;
try //Internet Explorer
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.load(file);
}
catch(e)
{
try //Firefox, Mozilla, Opera, etc.
{
xmlDoc=document.implementation.createDocument("","",null);
xmlDoc.async=false;
xmlDoc.load(file);
}
catch(e)
{
try //Google Chrome
{
var xmlhttp = new window.XMLHttpRequest();
xmlhttp.open("GET",file,false);
xmlhttp.send(null);
xmlDoc = xmlhttp.responseXML.documentElement;
}
catch(e)
{
error=e.message;
}
}
}
return xmlDoc;
}
function xslTransform(xmlObject, xslObject)
{
try
{
$("body").append("<div id='test'></div>");
var a = $("#test").transform({ xmlobj: xmlObject, xslobj: xslObject });
}
catch (exception)
{
if (typeof (exception) == "object" && exception.message)
alert(exception.message);
else alert(exception);
}
}
var xmlObject = loadXML("input.xml");
var xslObject = loadXML("transform.xsl");
$(document).ready(function()
{
xslTransform(xmlObject, xslObject);
});
</script>
</head>
<body>
</body>
</html>
Эта тестовая HTML-страница работает как в Chrome / FireFox / IE.
input.xml - это простой xml-файл, содержащий <root />
transform.xsl - это урезанный xsl, который вы опубликовали.
РЕДАКТИРОВАТЬ
Однако кажется, что $ .transform имеет проблемы с импортом таблиц стилей из включенных файлов:
Вот как это исправить:
Найти
var safariimportincludefix = function(xObj,rootConfig) {
in jquery.transform.js
и замените всю функцию следующим:
var safariimportincludefix = function(xObj,rootConfig) {
var vals = $.merge($.makeArray(xObj.getElementsByTagName("import")),$.makeArray(xObj.getElementsByTagName("include")));
for(var x=0;x<vals.length;x++) {
var node = vals[x];
$.ajax({
passData : { node : node, xObj : xObj, rootConfig : rootConfig},
dataType : "xml",
async : false,
url : replaceref(node.getAttribute("href"),rootConfig),
success : function(xhr) {
try {
var _ = this.passData;
xhr = safariimportincludefix(xhr,_.rootConfig);
var imports = $.merge(childNodes(xhr.getElementsByTagName("stylesheet")[0],"param"),childNodes(xhr.getElementsByTagName("stylesheet")[0],"template"));
var excistingNodes = [];
try
{
var sheet = _.xObj;
var params = childNodes(sheet,"param");
var stylesheets = childNodes(sheet,"template");
existingNodes = $.merge(params,stylesheets);
}
catch(exception)
{
var x = exception;
}
var existingNames = [];
var existingMatches = [];
for(var a=0;a<existingNodes.length;a++) {
if(existingNodes[a].getAttribute("name")) {
existingNames[existingNodes[a].getAttribute("name")] = true;
} else {
existingMatches[existingNodes[a].getAttribute("match")] = true;
}
}
var pn = _.node.parentNode;
for(var y=0;y<imports.length;y++) {
if(!existingNames[imports[y].getAttribute("name")] && !existingMatches[imports[y].getAttribute("match")]) {
var clonednode = _.xObj.ownerDocument.importNode(imports[y],true);
//pn.insertBefore(clonednode,_.xObj);
pn.insertBefore(clonednode,childNodes(_.xObj,"template")[0]);
}
}
pn.removeChild(_.node);
} catch(ex) {
}
}
});
}
return xObj;
};
Теперь, используя ранее вставленный тестовый index.html, используйте его для transform.xsl
:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:include href="include.xsl" />
<xsl:output method="html"/>
<xsl:template match="/">
<xsl:call-template name="giveMeAnIncludedHeader" />
</xsl:template>
</xsl:stylesheet>
А это для include.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="giveMeAnIncludedHeader">
<h1>Test</h1>
</xsl:template>
</xsl:stylesheet>
С ранее опубликованным исправлением в jquery.transform.js
теперь будет вставлено включенное <h1>Test</h1>
во все браузеры.
Вы можете увидеть это в действии здесь: http://www.mpdreamz.nl/xsltest