Javascript XSLTProcessor иногда не работает - PullRequest
1 голос
/ 19 сентября 2008

Следующий 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-код, а иногда нет. Кто-нибудь знает, где идет не так?

Ответы [ 5 ]

0 голосов
/ 21 сентября 2008

Вы вынуждены использовать синхронное решение, которое используете сейчас, или же вариант с асинхронным решением также доступен? Я помню, что в прошлом у 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 и выполнить преобразование.

0 голосов
/ 21 сентября 2008

Ниже приведена функция 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');
    }


}
0 голосов
/ 19 сентября 2008

Dan. 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>    

0 голосов
/ 19 сентября 2008

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

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

<BODY onLoad="ShowPopularTags();">

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

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

0 голосов
/ 19 сентября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...