Вопрос

Следующий код JavaScript предполагает считывание популярных тегов из XML-файла, применение таблицы стилей XSL и вывод в браузер в виде HTML.

function ShowPopularTags() {
   xml = XMLDocLoad("http://localhost/xml/tags/popular.xml?s=94987898");
   xsl = XMLDocLoad("http://localhost/xml/xsl/popular-tags.xsl");
   if (window.ActiveXObject) {
      // code for IE
      ex = xml.transformNode(xsl);
      ex = ex.replace(/\\/g, "");
      document.getElementById("popularTags").innerHTML = ex;
   } else if (document.implementation && document.implementation.createDocument) {
      // code for Mozilla, Firefox, Opera, etc.
      xsltProcessor = new XSLTProcessor();
      xsltProcessor.importStylesheet(xsl);
      resultDocument = xsltProcessor.transformToFragment(xml, document);
      document.getElementById("popularTags").appendChild(resultDocument);
      var ihtml = document.getElementById("popularTags").innerHTML;
      ihtml = ihtml.replace(/\\/g, "");
      document.getElementById("popularTags").innerHTML = ihtml;
   }
}
ShowPopularTags();

Проблема с этим сценарием в том, что иногда ему удается вывести результирующий HTML-код, а иногда нет.Кто-нибудь знает, что происходит не так?

Это было полезно?

Решение

Вы вынуждены использовать синхронное решение, которое используете сейчас, или асинхронное решение тоже возможно?Я помню, что в прошлом у Firefox были проблемы с синхронными вызовами, и я не знаю, сколько из них все еще сохраняется.Я видел ситуации, когда весь интерфейс Firefox блокировался на время выполнения запроса (что, в зависимости от настроек тайм-аута, может занять очень много времени).

С вашей стороны это потребует немного больше работы, но решение будет примерно таким.Это код, который я использую для обработки XSLT-материалов с помощью Ajax (немного переписал его, поскольку мой код объектно-ориентированный и содержит цикл, который анализирует соответствующий XSL-документ из сначала загруженного XML-документа).

Примечание:убедитесь, что вы объявили свою версию oCurrentRequest и oXMLRequest вне функций, поскольку она будет перенесена.

if (window.XMLHttpRequest)
{
  oCurrentRequest = new XMLHttpRequest();
  oCurrentRequest.onreadystatechange = processReqChange;
  oCurrentRequest.open('GET', sURL, true);
  oCurrentRequest.send(null);
}
else if (window.ActiveXObject)
{
  oCurrentRequest = new ActiveXObject('Microsoft.XMLHTTP');
  if (oCurrentRequest)
  {
    oCurrentRequest.onreadystatechange = processReqChange;
    oCurrentRequest.open('GET', sURL, true);
    oCurrentRequest.send();
  }
}

После этого вам просто понадобится функция с именемprocessReqChange, которая содержит что-то вроде следующего:

function processReqChange()
{
  if (oCurrentRequest.readyState == 4)
  {
    if (oCurrentRequest.status == 200)
    {
      oXMLRequest = oCurrentRequest;
      oCurrentRequest = null;
      loadXSLDoc();
    }
  }
}

И, конечно же, вам потребуется создать второй набор функций для обработки загрузки XSL (например, начиная с loadXSLDoc).

Затем в конце процесса XSLReqChange вы можете получить результат XML и результат XSL и выполнить преобразование.

Другие советы

Что ж, этот код следует совершенно разными путями для IE и всего остального.Я предполагаю, что проблема ограничивается одним из них.В каких браузерах вы пробовали это делать и в каких возникает эта ошибка?

Единственное, о чем я могу думать, это то, что элемент PopularTags может не существовать, когда вы пытаетесь что-то с ним сделать.Как выполняется эта функция?В событии onload/domready?

Дэн.IE выполняет скрипт без проблем.Я столкнулся с проблемой в Firefox.Элемент PopularTags существует в HTML-документе, который вызывает функцию.

<div id="popularTags" style="line-height:18px"></div>
<script language="javascript" type="text/javascript">
    function ShowPopularTags()
    {
        xml=XMLDocLoad("http://localhost/xml/tags/popular.xml?s=29497105");
        xsl=XMLDocLoad("http://localhost/xml/xsl/popular-tags.xsl");

        if (window.ActiveXObject){
            // code for IE
            ex=xml.transformNode(xsl);
            ex = ex.replace(/\\/g, "");
            document.getElementById("popularTags").innerHTML=ex;
        }
        else if (document.implementation && document.implementation.createDocument){
            // code for Mozilla, Firefox, Opera, etc.
            xsltProcessor=new XSLTProcessor();
            xsltProcessor.importStylesheet(xsl);
            resultDocument = xsltProcessor.transformToFragment(xml,document);
            document.getElementById("popularTags").appendChild(resultDocument);

            var ihtml = document.getElementById("popularTags").innerHTML;
            ihtml = ihtml.replace(/\\/g, "");
            document.getElementById("popularTags").innerHTML = ihtml;
         }
    }

    ShowPopularTags();
</script>    

Чтобы избежать проблем с параллельной загрузкой вещей (как намекнул Дэн), всегда полезно вызывать такие сценарии только после полной загрузки страницы.

В идеале вы помещаете теги сценария в заголовок страницы и вызываете ShowPopularTags();в теле элемента Onload.Т.е.

<BODY onLoad="ShowPopularTags();">

Таким образом, вы полностью уверены, что ваш document.getElementById("popularTags") не даст сбой, поскольку сценарий вызывается до полной загрузки HTML, содержащего элемент.

Кроме того, можем ли мы увидеть вашу функцию XMLDocLoad?Если он также содержит непоследовательные элементы, вы можете столкнуться с проблемой, когда преобразование XSLT происходит до полной загрузки объектов xml и xsl.

Ниже приведена функция XMLDocLoad.

function XMLDocLoad(fname)
{
    var xmlDoc;

    if (window.ActiveXObject){
        // code for IE
        xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async=false;
        xmlDoc.load(fname);

        return(xmlDoc);
    }
    else if(document.implementation && document.implementation.createDocument){
        // code for Mozilla, Firefox, Opera, etc.
        xmlDoc=document.implementation.createDocument("","",null);

        xmlDoc.async=false;
        xmlDoc.load(fname);

        return(xmlDoc);

    }
    else{
        alert('Your browser cannot handle this script');
    }


}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top