2015-01-24 6 views
0

EDITXML을 XMLHttprequest의 응답으로 바꿉니다.

내 질문에 대한 모든 수정 사항과 함께 상당히 길어졌습니다. 그래서 좀 더 짧게하고 더 쉽게 따르도록하겠습니다.

XULRunner를 사용하여 XUL 응용 프로그램을 작성하고 있습니다. 더미 XUL 페이지를로드 한 다음 XMLHttprequest을 사용하여 내 서버 (로컬 ampps 서버)에서 모든 것을로드합니다. PHP를 사용하여 모든 실제 작업을 수행합니다. PHP가 XML Content-Type 헤더를 설정하고 모든 출력 데이터의 형식을 XML로 지정합니다.

다음은 XMLHttprequest 및 응답을 처리하는 JavaScript 함수의 모양입니다.

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'); 
} 

RequestData()

는 윈도우 onload 이벤트를 호출합니다.

내 원래 코드는 아무 것도하지 않는 것처럼 보였지만, 연구하고 테스트 한 결과 XULRunner는 오류 콘솔에 오류를 표시했습니다. 궁극적으로 그것은 내가 현재 가정하고있는 버전으로 작동하지만 버전을 알지 못했습니다.

오류 콘솔이 메시지를 알리 (그리고 여전히)

경고했다

: 창 요소에 대한 XUL 상자가 인라인 도구 상자 아이를 포함, 모든 아이를 강제는 블록에 싸여있다.

내 코드가 작동하는지 확인하려면 Firefox에 넣어야합니다. 따라서 if (window.XMLHttpRequest)의 이유는 Firefox와 XULRunner를 사용하여 테스트 할 수 있기 때문입니다. 그런 다음 Firefox에서 로컬 파일 인 XMLHttprequest이 로컬 파일 인 경우에도 원격 파일을로드 할 수 없으므로 PHP에서 생성 한 XML을 가져 와서 로컬 파일을 만들었습니다.

위의 코드는 XML을 가져오고 <menubar id="menubarwrapper">...</menubar>을 대체합니다. 그러나 Firefox와 XULRunner 모두 메뉴가 사라집니다. Firebug를 사용하면 모든 요소를 ​​볼 수 있지만 더 이상 볼 수없는 이유는 나를 넘어서고 Firebug 콘솔에는 오류가 없습니다. 이것은 내가 지금 당황한 곳이다.

다음은 어떤 용도로든로드하는 더미 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> 

내 PHP가 생성하는 XML

은 매우 긴하지만, 기본적으로는 위의 유사 자식의 모든 요소를 ​​가진 <menubar> 요소이지만, 더 많은 <menu><menuitem> 요소.

+0

[DOM Inspector] (https://addons.mozilla.org/firefox/addon/dom-inspector-6622/)를 수정하여 문서 DOM이 수정 된 모양을 확인하십시오. 어떤 요소가''''xmlDoc.documentElement''''입니까? – Kashif

+0

@Kashif - DOM 검사기를 사용하지는 않았지만로드 한 후, 언뜻보기에 방화 벽에있는 것과 비슷한 정보가 나타납니다. 나는 firebug가 출력하고있는 것을보기 위해 Firefox에서 테스트를 만들었습니다. 자세한 내용은 내 두 번째 편집을 참조하십시오. – Krik

+0

@Kashif - 질문에 대한 답을 잊어 버렸습니다. xmlDoc.documentElement는 PHP – Krik

답변

0

나는 그것이 작동하지만 코드가 될 그 어느 필요 것보다 80 + 선 이상 얻었다. 나는 importNode, replaceChild, appendChild, adoptNode, removeChild 등의 모든 변형을 시도했다. 나는 생각할 수 있었다. 나는 주어진 XML 요소 나 노드를 얼마나 많은 방법으로 처리 할 수 ​​있는지에 대한 책을 쓸 수 있음을 확신한다.

다음은 얼마나 불합리한 문제인지 예입니다. 하지

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 단지 내용입니다이

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); 
} 

작동하지만이 것입니다. 심지어 문자열까지 xmlDoc을 직렬화 한 다음 다시 구문 분석하고 여전히 작동하지 않습니다. 나는 바보 같은 아이디어를 많이 보았고, 많은 사람들이 일하지 않을 것이라는 것을 알았습니다. 기회를 놓쳐서 문제에 대한 단서를 얻을 수있었습니다. Firefox를 크래시하면 너무 세게 밀었습니다.

하지만 나는 빗 나간다. XULRunner와 함께 XHR을 사용하려고하는 다른 사람들을 위해 아래해야 할 일이 있습니다.

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

더 이상의 정보가 없으면 이는 문제의 추측 일뿐입니다.

XMLHttpRequest()에서 검색된 XML 데이터가 XUL이 아닌 XML/HTML로 해석되고 있습니다. 이것은 당신이 묘사하는 행동을 초래할 수 있습니다. 당신은 당신의 선으로 삽입 된 요소를보고하기 위해 DOM Inspector를 사용하여이를 확인할 수 있습니다 : 당신은 무엇을 찾아야하는 Namespace URI 그 요소를 보여줍니다 무엇을

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

입니다. 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

namespaceURI가 "null"입니다. 제안 된 솔루션은 namespaceURI 문제를 해결하지만 "메뉴 모음"은 여전히 ​​표시하지 않습니다. 나는 그것이 메뉴 바의 대략 2px/툴바가 윈도우의 꼭대기에 보여지는 원인이되었다고 언급 할 것이다. PHP가 생성하는 XML 요청에 관해서는 위의 예제 코드에서 기본적으로 과 그 모든 자식을 생성합니다. 차이점은 PHP가 약 200+ 을 생성하고 있으므로 여기에 게시하면 내 게시물이 상당히 길어질 것입니다. 당신이 그것을 볼 필요가있는 다른 이유가 있다면 나는 부품을 벗겨서 게시 할 수 있습니다. – Krik

+0

@Krik : 필자가 설명한 기본 절차는 다른 Firefox 확장 프로그램에서 동적으로 생성 된 콘텐츠로 저에게 효과적입니다.문제의 정보 목표는 우리가 문제를 복제하고 해결책이 명확하지 않을 때 문제를 해결할 수있을만큼 충분히 확보하는 것입니다. 일반적으로 여기에는 여러 사람이 참여하지만 문제를 복제 할 수있는 충분한 정보가 필요합니다. 이것은 XML 스트라이프 다운 버전이 필요하다는 것을 의미합니다 (어쨌든 테스트해야합니다). – Makyen

관련 문제