2015-01-24 2 views
0

EDITЗаменить XML с ответом от XMLHttprequest

Со всеми изменениями по моему вопросу он довольно длительный. Поэтому позвольте мне попытаться немного укоротить его и облегчить его выполнение.

Я создаю приложение XUL с помощью XULRunner. Я загружаю страницу Dummy XUL, а затем я хочу использовать XMLHttprequest для загрузки всего с моего сервера (локального сервера ampps), используя PHP для выполнения всей реальной работы. Мой PHP настраивает заголовок XML Content-Type и форматирует все выходные данные как XML.

Вот что такое функция JavaScript, которая обрабатывает XMLHttprequest и ответ, в настоящее время выглядит.

function RequestData() 
{ 
if (window.XMLHttpRequest) 
{ 
    var url = 'newmenu.xml'; 
    var request = new XMLHttpRequest(); 
} 
else 
{ 
    var url = 'http://localdomain.prog/'; 
    var request = Components.classes['@mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Components.interfaces.nsIXMLHttpRequest); 
} 

request.onload = function(aEvent) 
{ 
    var xmlDoc = aEvent.target.responseXML; 

    var oldmenu = document.getElementById('menubarwrapper'); 

    oldmenu.parentNode.replaceChild(xmlDoc.documentElement, oldmenu); 
}; 
request.onerror = function(aEvent) 
{ 
    window.alert("Error Status: " + aEvent.target.status); 
}; 
request.open('POST', url, true); 
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
request.send('pageid=menu'); 
} 

The RequestData() вызывается с окном onload события.

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

Ошибки Консоль была тушением этого сообщения (и до сих пор)

Предупреждение: XUL коробка для оконного элемента содержала встроенные панели инструментов ребенка, заставляя все свои ребенок, чтобы быть обернут в блоке.

Чтобы узнать, работал ли мой код, мне пришлось его загрузить в Firefox. Отсюда причина для if (window.XMLHttpRequest), так как это позволяет мне тестировать как с Firefox, так и с XULRunner. Затем я взял XML, который генерировал мой PHP, и сделал локальный файл, так как Firefox не позволит XMLHttprequest загружать удаленный файл (даже если он является технически локальным).

Приведенный выше код импортирует XML и заменяет <menubar id="menubarwrapper">...</menubar>. Но в Firefox и XULRunner меню исчезает. Я могу видеть все элементы, если вы используете Firebug, но почему они больше не видны, выходит за меня, и ошибок в консоли Firebug нет. Здесь я в настоящее время тупик.

В случае его использования, ниже приведена копия файла Dummy XUL, который я загружаю.

<?xml version="1.0"?> 
<?xml-stylesheet href="main.css" type="text/css"?> 

<window id="main" title="My App" width="1000" height="800" sizemode="maximized" orient="vertical" persist="screenX screenY width height" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 

<script type="application/javascript" src="main.js"/> 

<toolbox id="toolboxwrapper"> 
    <menubar id="menubarwrapper"> 
     <menu id="file-menu" label="File" accesskey="F"> 
      <menupopup id="file-popup"> 
       <menuitem label="Refresh" funcname="RefreshWin"/> 
       <menuitem label="Open Window" funcname="OpenWin" acceltext="Ctrl+O" accesskey="O" /> 
       <menuseparator/> 
       <menuitem label="Exit" funcname="ExitProg"/> 
      </menupopup> 
     </menu> 
     <menu id="edit-menu" label="Edit" accesskey="E"> 
      <menupopup id="edit-popup"> 
       <menuitem label="Undo"/> 
       <menuitem label="Redo"/> 
      </menupopup> 
     </menu> 
    </menubar> 
</toolbox> 
</window> 

XML, который генерирует мой PHP является довольно длительным, но в основном это <menubar> элемент со всеми его дочерними элементами, аналогичными выше, но с гораздо более <menu> и <menuitem> элементов.

+0

Попробуйте [DOM Inspector] (https://addons.mozilla.org/firefox/addon/dom-inspector-6622/), чтобы проверить, как выглядит ваш документ DOM после его изменения. Какой элемент '' '' xmlDoc.documentElement''''? – Kashif

+0

@ Kashif - Я не использовал инспектор DOM, но после его загрузки, на первый взгляд, похоже, что он похож на то, что находится в Firebug. Я действительно создал тест в Firefox, чтобы узнать, что выводит firebug. Для получения дополнительной информации см. Мое второе редактирование. – Krik

+0

@ Kashif - забыл ответить на ваш вопрос. xmlDoc.documentElement - это элемент , который генерируется моим PHP – Krik

ответ

0

Я получил это работает, но код 80+ строки больше, чем когда-нибудь нужно. Я пробовал каждый вариант importNode, replaceChild, appendChild, adoptNode, removeChild, ect. Я мог подумать. Я вполне уверен, что могу написать книгу о том, как много способов вы могли бы обрабатывать любой XML-элемент или узел.

Вот пример того, насколько абсурдной была проблема. Это будет работать

function AddNewElem() 
{ 
    var menubar = document.getElementById('menubarwrapper'); 

    var menuitem = '<menu id="help-menu" label="Help" accesskey="H" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">'; 
    menuitem += '<menupopup id="help-popup">'; 
    menuitem += '<menuitem id="test-menu" label="Test" acceltext="Ctrl+T" accesskey="T" />'; 
    menuitem += '<menuseparator/>'; 
    menuitem += '<menuitem id="about-menu" label="About" acceltext="Ctrl+A" accesskey="A" />'; 
    menuitem += '</menupopup>'; 
    menuitem += '</menu>'; 

    var parser = new DOMParser(); 
    var xmlDoc = parser.parseFromString(menuitem, 'text/xml').documentElement; 

    menubar.appendChild(xmlDoc); 
} 

, но это будет не

function RequestData() 
{ 
    var url = 'newmenu.txt'; 
    var request = new XMLHttpRequest(); 

    request.onload = function(aEvent) 
    { 
     var menubar = document.getElementById('menubarwrapper'); 

     var responsetxt = aEvent.target.responseText; 

     var parser = new DOMParser(); 
     var xmlDoc = parser.parseFromString(responsetxt, 'text/xml').documentElement; 

     menubar.appendChild(xmlDoc); 
    }; 
    request.onerror = function(aEvent) 
    { 
     alert("Error Status: " + aEvent.target.status); 
    }; 
    request.open('POST', url, true); 
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
    request.send('pageid=menu'); 
} 

newmenu.txt является только содержание menuitem в предыдущем фрагменте кода. Я даже дошел до сериализации xmlDoc назад к строке, а затем снова проанализировал ее и все равно не сработал. Я попробовал массу глупых идей, и многие из которых, как я знал, не сработали, вовремя я мог бы получить представление об этой проблеме. Когда вы сталкиваетесь с Firefox, вы знаете, что слишком сильно зашли.

Но я отвлекся. Так что ради других, пытающихся использовать, XHR с XULrunner ниже - это то, что я должен был сделать.

function RequestData() 
{ 
    var url = 'http://localdomain.prog/'; 
    var request = Components.classes['@mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Components.interfaces.nsIXMLHttpRequest); 

    request.onload = function(aEvent) 
    { 
     var xmlDoc = aEvent.target.responseXML; 

     var toolbar = document.getElementById('toolboxwrapper'); 
     var menubar = document.getElementById('menubarwrapper'); 
     toolbar.removeChild(menubar); 

     var menubar = document.createElement('menubar'); 
     menubar.setAttribute('id', 'menubarwrapper'); 

     var docfrag = document.createDocumentFragment(); 
     docfrag.appendChild(menubar); 

     var newmenus = xmlDoc.getElementsByTagName('menu'); 
     var menuslen = newmenus.length; 
     for (var i = 0; i < menuslen; i++) 
     { 
      docfrag = CreateMenu(newmenus[i], docfrag); 
     } 

     toolbar.appendChild(docfrag); 
    }; 
    request.onerror = function(aEvent) 
    { 
     window.alert("Error Status: " + aEvent.target.status); 
    }; 
    request.open('POST', url, true); 
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
    request.send('pageid=menu'); 
} 

function CreateMenu(obj, docfrag) 
{ 
    var fragbar = docfrag.getElementById('menubarwrapper'); 

    var menu = document.createElement('menu'); 

    menu = SetMenuAttr(obj, 'id', menu); 
    menu = SetMenuAttr(obj, 'label', menu); 
    menu = SetMenuAttr(obj, 'accesskey', menu); 

    var fragmenu = fragbar.appendChild(menu); 

    var popup = obj.getElementsByTagName('menupopup')[0]; 

    var menupopup = document.createElement('menupopup'); 
    menupopup = SetMenuAttr(popup, 'id', menupopup); 

    var fragpopup = fragmenu.appendChild(menupopup); 

    if (popup.hasChildNodes()) 
    { 
     var childmenu = popup.childNodes; 

     var menulen = childmenu.length; 

     for (var i = 0; i < menulen; i++) 
     { 
      if (childmenu[i].nodeName == 'menuitem' || childmenu[i].nodeName == 'menu') 
      { 
       if (childmenu[i].nodeName == 'menuitem') 
       { 
        var menuitem = CreateMenuitem(childmenu[i]); 
       } 

       if (childmenu[i].nodeName == 'menu') 
       { 
        var menuitem = CreateMenu(childmenu[i]); 
       } 
       fragpopup.appendChild(menuitem); 
      } 
     } 
    } 
    return docfrag; 
} 

function CreateMenuitem(obj) 
{ 
    var menuitem = document.createElement('menuitem'); 

    menuitem = SetMenuAttr(obj, 'id', menuitem); 
    menuitem = SetMenuAttr(obj, 'label', menuitem); 
    menuitem = SetMenuAttr(obj, 'accesskey', menuitem); 
    menuitem = SetMenuAttr(obj, 'acceltext', menuitem); 
    menuitem = SetMenuAttr(obj, 'disabled', menuitem); 

    return menuitem; 
} 

function SetMenuAttr(obj, attr, newobj) 
{ 
    if (obj.hasAttribute(attr)) 
    { 
     newobj.setAttribute(attr, obj.getAttribute(attr)); 
    } 
    return newobj; 
} 

В основном необходимо было извлечь каждый элемент и его атрибуты и создать новые элементы. Безусловно, это не предпочтительное решение. Для меня, если мне нужно написать одну строку кода больше, чем это абсолютно необходимо, это неправильно. Решение должно быть 2 строки.

0

Без дополнительной информации это всего лишь догадка о том, в чем проблема.

Что может случиться, так это то, что данные XML, полученные из вашего XMLHttpRequest(), интерпретируются как XML/HTML, а не XUL. Это может привести к поведению, которое вы описываете. Вы можете проверить это с помощью DOM Inspector посмотреть на элементах, которые были вставлены с вашей линией:

oldmenu.parentNode.replaceChild(xmlDoc.documentElement, oldmenu); 

То, что вы должны смотреть на то, что Namespace URI показывает для этих элементов. Если это не http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul, то элементы не обрабатываются как XUL.

Одним из способов решения этой проблемы было бы сделать:

oldmenu.insertAdjacentHTML("afterend", aEvent.target.responseText); 
oldmenu.setAttribute("hidden","true"); 
//Alternately (if you don't want to keep the placeholder <menubar>): 
//oldmenu.parentNode.removeChild(oldmenu); 
+0

ИменапространствоURI равно "null". Ваше предлагаемое решение устраняет проблему namespaceURI, но «menubar», но ее пока не отображается. Я бы прокомментировал, что это вызвало около 2px панели меню/панели инструментов в верхней части окна, где, как и раньше, не было. Что касается вашего запроса XML, который мой PHP производит, в основном, в моем примере кода выше, его и все его дети. Единственное отличие состоит в том, что PHP создает около 200+ , поэтому его размещение здесь увеличит мой пост совсем немного. Если есть какая-то другая причина, вам нужно это увидеть, я мог бы вырезать детали и опубликовать их. – Krik

+0

@Krik: Основная процедура, которую я описал, работает для меня с динамически созданным контентом в другом расширении Firefox.Цель информации в вопросе состоит в том, чтобы иметь достаточно, чтобы мы могли дублировать проблему и иметь возможность работать над ее решением, когда решение не очевидно. В общем, здесь есть несколько человек, которые будут работать над этим, но нам нужно достаточно информации, чтобы иметь возможность дублировать проблему. Это означает, что нам нужна, по крайней мере, небольшая версия вашего XML (что-то, что вы должны тестировать в любом случае). – Makyen

Смежные вопросы