2013년 6월 26일 수요일

[eclipse] 주석 달기 단축키 및 template 작성 방법

* 단축키
Shift + Alt + J

* 주석 template
창(W) - 환경설정(P) - Java - Code Style - Code Template

Comments에서 지정하고자 하는 template을 선택 후 edit 하면 되겠다.

2013년 5월 29일 수요일

[전자정부프레임워크] 중복 저장 막기위한 @SessionAttributes 지정 후 HttpSessionRequiredException handling

SessionAttribute

1. @SessionAttributes
model attribute를 session에 저장, 유지할 때 사용하는 어노테이션
사용목적 : 연속으로 client 로 부터 submit 이 날라오는 경우 중복 submit 을 방지할 때 이용
Controller 의 메소드에서 SessionStatus의 isComplete() 확인을 통해 Session내에 지정된 model 이 있는지 체크/중복(실행) 가능.



2. Session 유지기간, 초기화 방법
유지기간 : SessionStatus.setComplete()을 실행하기 전까지는 Session에서 내부의 데이터를 유지
초기화 방법 : SessionStatus.setComplete()을 실행하면 Controller에서 선언해둔 SssionAttribute에 등록된 form이 초기화


* 중복 저장 회피 방법
Data를 Add한 후에 redirect로 List.do 화면으로 이동


* List 화면으로 넘기는 parameter가 존재해서 forward로 List.do 화면으로 이동하고 싶을 때

중복 저장 Exception 발생 과정
(저자 혼자만의 정리, 그냥 이렇겠거니 혼자만의 생각)
  • 중복 저장 전, setComplete() method 호출로 인해 Session 내 form 정보 초기화
  • addData.do를 다시 실행
  • 저장을 위한 SessionAttribute로 지정한 form Data 접근
  • 초기환 된 데이터로 인해 HttpSessionRequiredException 발생
  • org.springframework.web.servlet.handler.SimpleMappingExceptionResolver에 의해 사용자가 지정한 errorPage로 이동 (페이지 이동 설정파일 : dispatcher-servlet.xml)
Exception handling 방법 - errorPage에서 어떤 Form에 의해서 Exception이 발생했는지에 따라 각 화면 List.do로 재 forward.
(이것 또한 지극히 혼자만의 생각. 이렇게 하면 될 것 같아서...;;)

구현 방법
1. dispatcher-servlet.xml에 HttpSessionRequiredException 추가
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="defaultErrorView" value="cmmn/bizError"/>
        <property name="exceptionMappings">
            <props>
                <prop key="org.springframework.dao.DataAccessException">cmmn/dataAccessFailure</prop>
                <prop key="org.springframework.transaction.TransactionException">cmmn/transactionFailure</prop>
                <prop key="egovframework.rte.fdl.cmmn.exception.EgovBizException">cmmn/bizError</prop>
                <prop key="org.springframework.security.AccessDeniedException">cmmn/accessDenied</prop>
                <prop key="org.springframework.web.HttpSessionRequiredException">cmmn/httpsession</prop>
            </props> <!-- 추가한 부분 -->
        </property>
    </bean>

2. httpsession.jsp 구성

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set value="${exception.message}" var="error"></c:set>
<c:if test="${fn:contains(error,'sampleVO')}">
<jsp:forward page="/sample/egovSampleList.do"/>
</c:if>

2013년 5월 12일 일요일

[javascript] 새로고침 막는 방법



<script language="javascript">
//새로 고침 방지 기능 실행
function LockF5(){
 if (event.keyCode == 116) {
  event.keyCode = 0;
  return false;
 }
}
document.onkeydown = LockF5;
</script>
[출처] F5 새로고침 방지 |작성자 minhi1000
→ IE8에서 제대로 작동 안 함(크롬에서는 작동)


*IE8에서 작동하다록 하는 방법


document.onkeydown=function(e) {
    var event = window.event || e;
    if (event.keyCode == 116) {
        event.keyCode = 0;
        alert("This action is not allowed");
        return false;
    }
}

2013년 5월 9일 목요일

[javascript] jsonStringData → html table 구조로 print하기



search버튼 눌렀을 때 server response 밑에 나오는 table 구조의 customer 정보들
servlet에서 arrayList를 json으로 포맷 변환 후, response.(바로 직전 게시글 참조)

ajax로 호출 후 response 받은 jsonString data를 화면에 print

나머지 소스는 생략하고, javascript에서 print 해주는 부분만 발췌!
------------------------------------------------------------------
function crateTableRow(row, data, cellType) {
   var cell = document.createElement(cellType);
  var textNode = document.createTextNode(data);
  cell.appendChild(textNode); row.appendChild(cell);
}


function createTableData(row, data) {
  crateTableRow(row, data, "td");
}

function createTableHeader(row, data) {
  crateTableRow(row, data, "th");
}

function displayJSON(jsonString) {
  var json = JSON.parse(jsonString); //servlet에서 넘겨준 jsonString 값을 json으로 parsing
  var table = document.createElement("table");

  var thead = document.createElement("thead");
  table.appendChild(thead);
  var row = document.createElement("tr");
  createTableHeader(row,"Name");
  createTableHeader(row,"Age");
  createTableHeader(row,"Tel");
  createTableHeader(row,"Addr");
  thead.appendChild(row);

  var tbody = document.createElement("tbody");
  table.appendChild(tbody);
  for(var i=0; i<json.customers.length; i++) {
  var row = document.createElement("tr");
  createTableData(row,json.customers[i].name);
      createTableData(row,json.customers[i].age);
createTableData(row,json.customers[i].tel);
createTableData(row,json.customers[i].addr);
tbody.appendChild(row);
}
document.getElementById("serverResponse").innerHTML = "";
  document.getElementById("serverResponse").appendChild(table); }
------------------------------------------------------------------

[java] java arraylist → JSON으로 변경하기

ajax 테스트하다 보니 text 형태로 값을 return 하던데 그럼 arraylist Type은?

바로 넘겨줄 수 있는 줄 알았더니 그게 아니더군..-_-;;
arraylist를 잘 표현할 수 있는 것이 xml, json이라는 지인의 말.
(혹시 다른 방법이 있다면 commnet 좀..;;)

그리하여 구글링 하다가 찾은 java arraylist를 json으로 변경하는 logic


클라이언트에서 ajax로 요청했을 때 자료를 손쉽게 파싱하기 위해서 json으로 클라이언트에 던져줄 때가 편할 때가 있습니다. 그래서 손쉽게 json으로 변환하는 라이브러리가 있습니다.

http://json-lib.sourceforge.net/

여기보면 json-lib라는 놈이 있는데 json으로 손쉽게 변환해주는 라이브러리입니다.


  • jakarta commons-lang 2.5
  • jakarta commons-beanutils 1.8.0
  • jakarta commons-collections 3.2.1
  • jakarta commons-logging 1.1.1
  • ezmorph 1.0.6
    이것들이 필요하다더군요. 위에 4개는 apache에 가면 있구요.
    ezmorph는 http://ezmorph.sourceforge.net/에 있습니다.

    사용법은 매우 간단합니다.
    [code]
    public class JsonTest {

     @Test
     public void Bean2Json()
     {
      MyBean myBean1 = new MyBean();
      myBean1.setId(1);
      myBean1.setName("mudchobo");
      MyBean myBean2 = new MyBean();
      myBean2.setId(2);
      myBean2.setName("shit");

      List<MyBean> mybeanList = new ArrayList<MyBean>();
      mybeanList.add(myBean1);
      mybeanList.add(myBean2);

      JSONArray jsonArray = JSONArray.fromObject(mybeanList);
      System.out.println("mybeanList - " + jsonArray);

      Map<String, Object> map = new HashMap<String, Object>();
      map.put("beanlist", jsonArray);

      JSONObject jsonObject = JSONObject.fromObject(map);
      System.out.println("json - " + jsonObject);
     }
    }
    [/code]
    Bean 2개를 List에 add를 한다음에 JSONArray라는 객체가 List를 배열로 만드는놈입니다.

    mybeanList - [{"id":1,"name":"mudchobo"},{"id":2,"name":"shit"}]

    이런식으로 만듭니다.
    저거를 JSONObject클래스를 이용해서 앞에 이름을 붙여줍니다. Map을 이용하면 됩니다
    Map을 이용해서 put에서 첫번째 인자에 이름을 넣고, 두번째 인자에 방금 생성한 Array를 넣으면 됩니다.
    그리고 JSONObject.fromObject메소드를 이용해서 생성하게 되면 이렇게 됩니다.

    json - {"beanlist":[{"id":1,"name":"mudchobo"},{"id":2,"name":"shit"}]}

    이상입니다-_-;


  • 출처 : http://mudchobo.tistory.com/275

    [ajax] 입문 예제(servlet 사용)

    <test.html>
    ------------------------------------------------------------

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Sending Request Data Using GET and POST</title>
    <script type="text/javascript">
    var xmlHttp;
    /*
    function createXMLHttpRequest() {
    if (window.ActiveXObject) {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    } else if (window.XMLHttpRequest) {
    xmlHttp = new XMLHttpRequest();
    }
    }
    */

    function createXMLHttpRequest() {
       if (window.ActiveXObject) {
           try {
               return new ActiveXObject("Msxml2.XMLHTTP");//IE 상위 버젼
           } catch (e1) {
               try {
                   return new ActiveXObject("Microsoft.XMLHTTP");//IE 하위 버젼
               } catch (e2) {
                   return null;
               }
           }
       } else if (window.XMLHttpRequest) {
           return new XMLHttpRequest();//IE 이외의 브라우저(FireFox 등)
       } else {
           return null;
       }
    }// XMLHttpRequest 객체 얻기

    function createQueryString() {
    var firstName = document.getElementById("firstName").value;
    var middleName = document.getElementById("middleName").value;
    var birthday = document.getElementById("birthday").value;

    var queryString = "firstName=" + firstName + "&middleName="
    + middleName + "&birthday=" + birthday;

    return queryString;
    }

    function doRequestUsingGET() {
    alert("doRequestUsingGET");
    xmlHttp = createXMLHttpRequest();

    var queryString = "ajaxResponseTestServlet?";
    queryString = queryString + createQueryString() + "&timeStamp="
    + new Date().getTime();
    xmlHttp.onreadystatechange = handleStateChange;
    xmlHttp.open("GET", queryString, true);
    xmlHttp.send(null);
    }

    function doRequestUsingPOST() {
    alert("doRequestUsingPOST");
    xmlHttp = createXMLHttpRequest();

    var url = "ajaxResponseTestServlet?timeStamp=" + new Date().getTime();
    var queryString = createQueryString();

    xmlHttp.open("POST", url, true);
    xmlHttp.onreadystatechange = handleStateChange;
    xmlHttp.setRequestHeader("Content-Type",
    "application/x-www-form-urlencoded;charset=utf-8");            
                                                                      → 한글 때문에
    xmlHttp.send(queryString);
    }

    function handleStateChange() {
    if (xmlHttp.readyState == 4) {
    if (xmlHttp.status == 200) {
    parseResults();
    }
    }
    }

    function parseResults() {
    var responseDiv = document.getElementById("serverResponse");
    if (responseDiv.hasChildNodes()) {
    responseDiv.removeChild(responseDiv.childNodes[0]);
    }

    var responseText = document.createTextNode(xmlHttp.responseText);
    responseDiv.appendChild(responseText);
    }
    </script>
    </head>
    <body>
    <h1>Enter your first name, middle name, and birthday:</h1>

    <table>
    <tbody>
    <tr>
    <td>First name:</td>
    <td><input type="text" id="firstName"/></td>
    </tr>
    <tr>
    <td>Middle name:</td>
    <td><input type="text" id="middleName"/></td>
    </tr>
    <tr>
    <td>Birthday:</td>
    <td><input type="text" id="birthday"/></td>
    </tr>
    </tbody>

    </table>

    <form action="#">
    <input type="button" value="Send parameters using GET"
    onclick="doRequestUsingGET();" />

    <br />
    <br />
    <input type="button" value="Send parameters using POST"
    onclick="doRequestUsingPOST();" />
    </form>
    <br />
    <h2>Server Response:</h2>
    <div id="serverResponse"></div>
    </body>
    </html>
    ------------------------------------------------------------
    인터넷에서 사용하는 소스를 가지고 테스트를 했는데, 왜 에러가 나는거니..
    (어쨌든 수정 후, 테스트 완료!)


    <ajaxResponseTestServlet>
    eclipse juno version은 web.xml이 없다.
    servlet을 생성하고 한참 web.xml을 찾았는데 java파일을 보니 annotation 마크와 함께 뭔가가 생성. (익숙했던 방법이 아니라 멍....;;)
    ------------------------------------------------------------

    package test;

    import java.io.IOException;
    import java.io.PrintWriter;

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    /**
     * Servlet implementation class ajaxResponseTestServlet
     */
    @WebServlet("/ajaxResponseTestServlet")
    public class ajaxResponseTestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void processRequest(HttpServletRequest request,
    HttpServletResponse response, String method)
    throws ServletException, IOException {

    // Set content type of the response to text/xml
    response.setContentType("text/xml");
    response.setCharacterEncoding("utf-8"); → 한글 때문에

    // Get the user's input
    String firstName = request.getParameter("firstName");
    String middleName = request.getParameter("middleName");
    String birthday = request.getParameter("birthday");

    // Create the response text
    String responseText = "Hello " + firstName + " " + middleName
    + ". Your birthday is " + birthday + "." + " [Method: "
    + method + "]";

    // Write the response back to the browser
    PrintWriter out = response.getWriter();
    out.println(responseText);
    // Close the writer
    out.close();
    }

    /**
    * @see HttpServlet#HttpServlet()
    */
    public ajaxResponseTestServlet() {
    super();
    // TODO Auto-generated constructor stub
    }

    /**
    * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
    *      response)
    */
    protected void doGet(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    System.out.println("GET");
    processRequest(request, response, "GET");
    }

    /**
    * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
    *      response)
    */
    protected void doPost(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
    // TODO Auto-generated method stub
    System.out.println("POST");
    processRequest(request, response, "POST");
    }

    }
    ------------------------------------------------------------

    2012년 10월 10일 수요일

    [JSP] xml 포맷 그대로 표현하기

    기존 JSP에서 xml데이터 포맷 그대로 보여주고 싶을 때
    (실제로 html과 xml은 언어 자체가 달라서 두 개를 같이 표현을 해 줄 수가 없다. 찾아보니 그러한 기능을 js와 css를 사용해서 구현한 사이트가 있어서 샘플을 만들었다. 
    구글링 만세!)

    -------------------------------------------------------
    index.jsp
    -------------------------------------------------------
    <%@ page language="java" contentType="text/html; charset=EUC-KR"
        pageEncoding="EUC-KR"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
    <title>Insert title here</title>
    </head>
    <body>
    <div id="XMLHolder"></div>
    <LINK href='XMLDisplay.css' type='text/css' rel='stylesheet'>
    <script type='text/javascript' src='XMLDisplay.js'></script>
    <script>LoadXML('XMLHolder','test.xml');</script>
    </body>
    </html>

    **테스트용이었으므로 css파일, js파일, jsp파일 모두 같은 위치에 배치

    -------------------------------------------------------
    XMLDisplay.js
    -------------------------------------------------------
    /* Copyright (c) 2007 Lev Muchnik <LevMuchnik@gmail.com>. All rights reserved.
     * You may copy and modify this script as long as the above copyright notice,
     * this condition and the following disclaimer is left intact.
     * This software is provided by the author "AS IS" and no warranties are
     * implied, including fitness for a particular purpose. In no event shall
     * the author be liable for any damages arising in any way out of the use
     * of this software, even if advised of the possibility of such damage.
     * $Date: 2007-10-03 19:08:15 -0700 (Wed, 03 Oct 2007) $
     */

    function LoadXML(ParentElementID,URL) 
    {
    var xmlHolderElement = GetParentElement(ParentElementID);
    if (xmlHolderElement==null) { return false; }
    ToggleElementVisibility(xmlHolderElement);
    return RequestURL(URL,URLReceiveCallback,ParentElementID);
    }
    function LoadXMLDom(ParentElementID,xmlDoc) 
    {
    if (xmlDoc) {
    var xmlHolderElement = GetParentElement(ParentElementID);
    if (xmlHolderElement==null) { return false; }
    while (xmlHolderElement.childNodes.length) { xmlHolderElement.removeChild(xmlHolderElement.childNodes.item(xmlHolderElement.childNodes.length-1)); }
    var Result = ShowXML(xmlHolderElement,xmlDoc.documentElement,0);
    var ReferenceElement = document.createElement('div');
    var Link = document.createElement('a');
    Link.setAttribute('href','http://www.levmuchnik.net/Content/ProgrammingTips/WEB/XMLDisplay/DisplayXMLFileWithJavascript.html');
    //var TextNode = document.createTextNode('Source: Lev Muchnik');
    Link.appendChild(TextNode);

    xmlHolderElement.appendChild(Link);
    return Result;
    }
    else { return false; }
    }
    function LoadXMLString(ParentElementID,XMLString) 
    {
    xmlDoc = CreateXMLDOM(XMLString);
    return LoadXMLDom(ParentElementID,xmlDoc) ;
    }
    ////////////////////////////////////////////////////////////
    // HELPER FUNCTIONS - SHOULD NOT BE DIRECTLY CALLED BY USERS
    ////////////////////////////////////////////////////////////
    function GetParentElement(ParentElementID)
    {
    if (typeof(ParentElementID)=='string') { return document.getElementById(ParentElementID); }
    else if (typeof(ParentElementID)=='object') { return ParentElementID;} 
    else { return null; }
    }
    function URLReceiveCallback(httpRequest,xmlHolderElement)
    {
     try {
                if (httpRequest.readyState == 4) {
                    if (httpRequest.status == 200) {
    var xmlDoc = httpRequest.responseXML;
    if (xmlHolderElement && xmlHolderElement!=null) {
    xmlHolderElement.innerHTML = '';
    return LoadXMLDom(xmlHolderElement,xmlDoc);
    }
                    } else {
                        return false;
                    }
                }
            }
            catch( e ) {
                return false;
            }
    }
    function RequestURL(url,callback,ExtraData) { // based on: http://developer.mozilla.org/en/docs/AJAX:Getting_Started
            var httpRequest;
            if (window.XMLHttpRequest) { // Mozilla, Safari, ...
                httpRequest = new XMLHttpRequest();
                if (httpRequest.overrideMimeType) { httpRequest.overrideMimeType('text/xml'); }
            } 
            else if (window.ActiveXObject) { // IE
                try { httpRequest = new ActiveXObject("Msxml2.XMLHTTP");   } 
                catch (e) {
      try { httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); } 
      catch (e) {}
                }
            }
            if (!httpRequest) { return false;   }
            httpRequest.onreadystatechange = function() { callback(httpRequest,ExtraData); };
            /* xml위치 : /WebContent/file/ */
            httpRequest.open('GET', "http://localhost:8080/Text/file/"+url, true);
            httpRequest.send('');
    return true;
        }
    function CreateXMLDOM(XMLStr) 
    {
    if (window.ActiveXObject)
    {
     xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); 
     xmlDoc.loadXML(XMLStr);
     return xmlDoc;
    }
    else if (document.implementation && document.implementation.createDocument)  {
     var parser=new DOMParser();
     return parser.parseFromString(XMLStr,"text/xml");
    }
    else {
    return null;
    }
    }

    var IDCounter = 1;
    var NestingIndent = 40;
    function ShowXML(xmlHolderElement,RootNode,indent)
    {
    if (RootNode==null || xmlHolderElement==null) { return false; }
    var Result  = true;
    var TagEmptyElement = document.createElement('div');
    TagEmptyElement.className = 'Element';
    TagEmptyElement.style.position = 'relative';
    TagEmptyElement.style.left = NestingIndent+'px';
    if (RootNode.childNodes.length==0) { 
        var ClickableElement = AddTextNode(TagEmptyElement,'','Clickable') ;
        ClickableElement.id = 'div_empty_' + IDCounter;  
        AddTextNode(TagEmptyElement,'<','Utility') ;
        AddTextNode(TagEmptyElement,RootNode.nodeName ,'NodeName') 
        for (var i = 0; RootNode.attributes && i < RootNode.attributes.length; ++i) {
          CurrentAttribute  = RootNode.attributes.item(i);
          AddTextNode(TagEmptyElement,' ' + CurrentAttribute.nodeName ,'AttributeName') ;
          AddTextNode(TagEmptyElement,'=','Utility') ;
          AddTextNode(TagEmptyElement,'"' + CurrentAttribute.nodeValue + '"','AttributeValue') ;
        }
        AddTextNode(TagEmptyElement,' />') ;
        xmlHolderElement.appendChild(TagEmptyElement);
        //SetVisibility(TagEmptyElement,true);    
    }
    else { // mo child nodes
        
        var ClickableElement = AddTextNode(TagEmptyElement,'+','Clickable') ;
        ClickableElement.onclick  = function() {ToggleElementVisibility(this); }
        ClickableElement.id = 'div_empty_' + IDCounter;
        AddTextNode(TagEmptyElement,'<','Utility') ;
        AddTextNode(TagEmptyElement,RootNode.nodeName ,'NodeName') 
        for (var i = 0; RootNode.attributes && i < RootNode.attributes.length; ++i) {
          CurrentAttribute  = RootNode.attributes.item(i);
          AddTextNode(TagEmptyElement,' ' + CurrentAttribute.nodeName ,'AttributeName') ;
          AddTextNode(TagEmptyElement,'=','Utility') ;
          AddTextNode(TagEmptyElement,'"' + CurrentAttribute.nodeValue + '"','AttributeValue') ;
        }

        AddTextNode(TagEmptyElement,'>  </','Utility') ;
        AddTextNode(TagEmptyElement,RootNode.nodeName,'NodeName') ;
        AddTextNode(TagEmptyElement,'>','Utility') ;
        xmlHolderElement.appendChild(TagEmptyElement);
        SetVisibility(TagEmptyElement,false);
        //----------------------------------------------
        
        var TagElement = document.createElement('div');
        TagElement.className = 'Element';
        TagElement.style.position = 'relative';
        TagElement.style.left = NestingIndent+'px';
        ClickableElement = AddTextNode(TagElement,'-','Clickable') ;
        ClickableElement.onclick  = function() {ToggleElementVisibility(this); }
        ClickableElement.id = 'div_content_' + IDCounter;
        ++IDCounter;
        AddTextNode(TagElement,'<','Utility') ;
        AddTextNode(TagElement,RootNode.nodeName ,'NodeName') ;
        
        for (var i = 0; RootNode.attributes && i < RootNode.attributes.length; ++i) {
            CurrentAttribute  = RootNode.attributes.item(i);
            AddTextNode(TagElement,' ' + CurrentAttribute.nodeName ,'AttributeName') ;
            AddTextNode(TagElement,'=','Utility') ;
            AddTextNode(TagElement,'"' + CurrentAttribute.nodeValue + '"','AttributeValue') ;
        }
        AddTextNode(TagElement,'>','Utility') ;
        TagElement.appendChild(document.createElement('br'));
        var NodeContent = null;
        for (var i = 0; RootNode.childNodes && i < RootNode.childNodes.length; ++i) {
          if (RootNode.childNodes.item(i).nodeName != '#text') {
            Result &= ShowXML(TagElement,RootNode.childNodes.item(i),indent+1);
          }
          else {
            NodeContent =RootNode.childNodes.item(i).nodeValue;
          }
        }
        if (RootNode.nodeValue) {
          NodeContent = RootNode.nodeValue;
        }
        if (NodeContent) {
          var ContentElement = document.createElement('div');
          ContentElement.style.position = 'relative';
          ContentElement.style.left = NestingIndent+'px';
          AddTextNode(ContentElement,NodeContent ,'NodeValue') ;
          TagElement.appendChild(ContentElement);
        }
        AddTextNode(TagElement,'  </','Utility') ;
        AddTextNode(TagElement,RootNode.nodeName,'NodeName') ;
        AddTextNode(TagElement,'>','Utility') ;
        xmlHolderElement.appendChild(TagElement);
      }
    // if (indent==0) { ToggleElementVisibility(TagElement.childNodes(0)); } - uncomment to collapse the external element
    return Result;
    }
    function AddTextNode(ParentNode,Text,Class) 
    {
    NewNode = document.createElement('span');
    if (Class) {  NewNode.className  = Class;}
    if (Text) { NewNode.appendChild(document.createTextNode(Text)); }
    if (ParentNode) { ParentNode.appendChild(NewNode); }
    return NewNode;
    }
    function CompatibleGetElementByID(id)
    {
    if (!id) { return null; }
    if (document.getElementById) { // DOM3 = IE5, NS6
    return document.getElementById(id);
    }
    else {
    if (document.layers) { // Netscape 4
    return document.id;
    }
    else { // IE 4
    return document.all.id;
    }
    }
    }
    function SetVisibility(HTMLElement,Visible)
    {
    if (!HTMLElement) { return; }
    var VisibilityStr  = (Visible) ? 'block' : 'none';
    if (document.getElementById) { // DOM3 = IE5, NS6
    HTMLElement.style.display =VisibilityStr; 
    }
    else {
    if (document.layers) { // Netscape 4
    HTMLElement.display = VisibilityStr; 
    }
    else { // IE 4
    HTMLElement.id.style.display = VisibilityStr; 
    }
    }
    }
    function ToggleElementVisibility(Element)
    {
    if (!Element|| !Element.id) { return; }
    try {
    ElementType = Element.id.slice(0,Element.id.lastIndexOf('_')+1);
    ElementID = parseInt(Element.id.slice(Element.id.lastIndexOf('_')+1));
    }
    catch(e) { return ; }
    var ElementToHide = null;
    var ElementToShow= null;
    if (ElementType=='div_content_') {
    ElementToHide = 'div_content_' + ElementID;
    ElementToShow = 'div_empty_' + ElementID;
    }
    else if (ElementType=='div_empty_') {
    ElementToShow= 'div_content_' + ElementID;
    ElementToHide  = 'div_empty_' + ElementID;
    }
    ElementToHide = CompatibleGetElementByID(ElementToHide);
    ElementToShow = CompatibleGetElementByID(ElementToShow);
    if (ElementToHide) { ElementToHide = ElementToHide.parentNode;}
    if (ElementToShow) { ElementToShow = ElementToShow.parentNode;}
    SetVisibility(ElementToHide,false);
    SetVisibility(ElementToShow,true);
    }

    -------------------------------------------------------
    XMLDisplay.css
    -------------------------------------------------------
    @charset "utf-8";
    /* CSS Document */
    .Utility {
    color: black;
    }
    .NodeName {
    font-weight:bold;
    color: #800080;
    }
    .AttributeName 
    {
    font-weight:bold;
    color: black;
    }
    .AttributeValue
    {
    color:blue;
    }
    .NodeValue
    {
    color: black;
    }
    .Element {
    border-left-color:#FFFFFF;
    border-left-width:thin;
    border-left-style:solid;
    padding-top:0px;
    margin-top:10px;
    }
    .Clickable {
    font-weight:900;
    font-size:large;
    color: #800080;
    cursor:pointer;

    vertical-align:middle;
    }