Ajax - XSLT 사용하기

Published on: 2009. 7. 13. 15:40 by louis.dev


Ajax를 사용할때 보통은 xml데이터를 사용하고 노드 탐색을 하여 데이터를 검출한뒤 사용할 곳에 직접 넣어 사용하는 방식을 취한다.

이렇게 되면 직접 style-sheet를 선언해야 하고 또한 매우 복잡한 형태가 된다.

그래서 XSLT 사용한다. XSLT는 실제적으로 보면  XML 데이터지만 거기에 html과 같은 태그와 함께 style-sheet까지 적용되어서 xml데이터만 연동할때 보다 훨신 편하게 xml데이터를 적용할 수 있게 된다.


다음 그림은 struts 2와 Ajax의 실행 순서를 그린 그림이다.
① fun1() function이 실행 되면 Ajax Engine으로 가서 다음과 같은 로직을 탄다.
② 모든 데이터를 수행하면 response XML을 통해 XML데이터를 리턴하게 된다.
③ XML 파일은 callback함수로 넘어간다.
④ fun2() function은 fun3() function을 호출하여 xsl 파일을 호출하고 XSLT로 가서 UI를 생성하고 그 데이터를 fun4() funtion으로 리턴하게 된다.

작업순서

1. xml 파일이 xsl로 가야 하기 때문에 XML을 만드는 작업을 먼저 해야 한다.

var xmlDoc = null; //변수 하나는 xml을 얻기 위해
var xslDoc = null; //xsl을 얻기 위해
 
  function loadList(num,goods) { //goods 파일 이름
      qty = document.buyform.qty[parseInt(num)].value;
      if(parseInt(qty) > 10 || parseInt(qty) < 1){
       alert('1 ~ 10개까지 구입이 가능합니다.');
       document.buyform.qty[parseInt(num)].focus();
       return;
      }
   param = "goods="+goods+
        "&name="+document.buyform.name.value +
        "&qty="+qty;
   sendRequest("cart.action", param, loadedCartXML, "POST");  //sendRequest는 httpRequest.js 에 있는 method
                                                                                                         //cart.action으로 데이터를 전송하고 다음 메소드인 loadedCartXML 
                                                                                                         //을 callback한다.
  }
  
  function loadedCartXML() {
   if (httpRequest.readyState == 4) {
    if (httpRequest.status == 200) {
     xmlDoc = httpRequest.responseXML;                     //전송된 xml데이터를 xmlDoc라는 변수에 저장한다.
     sendRequest("cart.xsl", null, loadedCartXSL, "POST");      //xsl파일로 이동하고 callback으로 loadCartXSL로 이동한다.
    }
   }
  }
  function loadedCartXSL() {
   if (httpRequest.readyState == 4) {
    if (httpRequest.status == 200) {
     xslDoc = httpRequest.responseXML;                                 //xsl에서 수행한 데이터도 xml데이터기 때문에 responseXML로 받는다.
     doXSLT();
    }
   }
  }
  
  function doXSLT() {
   if (xmlDoc == null || xslDoc == null) return;
   
   var list = document.getElementById("cartList");
//internet explorer 일때
   if (window.ActiveXObject) {
    list.innerHTML = xmlDoc.transformNode(xslDoc);                  //transformNode()메소드로 xsl결과를 출력한다.
//explorer가 아닐때  
 } else {
    var xsltProc = new XSLTProcessor();
    xsltProc.importStylesheet(xslDoc);
    var fragment = xsltProc.transformToFragment(xmlDoc, document);
    list.appendChild(fragment);
   }
  }

2. xsl파일이 XSLT로 가려면 중간에 DTD문서가 존재해야 한다.(DTD문서는 확장자는 dtd, xsl파일이름과 같은 경로,같은 이름이어야 한다)
xml 데이터가 다음과 같다면
-------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="euc-kr" ?>
<%@ page contentType="text/xml; charset=EUC-KR"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<cartlist>
 <s:iterator value="cartlist">
  <cart id="${filename}">
   <goods>${goods}</goods>
   <qty>${qtystr}</qty>
   <cost>${coststr}</cost>
   <amount>${amountstr}</amount>
   <filename>${filename}</filename>
     </cart>
 </s:iterator>
  <qtysum>${qtySum}</qtysum>
  <amountsum>${amountSumstr}</amountsum>
</cartlist>
-------------------------------------------------------------------------------------------
dtd문서는
-------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="euc-kr"?>

<!ELEMENT cartlist (cart*)> <!-- cartlist안에 cart라는 eliment *(0개 이상) -->
 <!ELEMENT cart (goods, qty, cost, amount, filename*, qtysum*, amountsum*)> <!-- cart 라는 element들은 ()안과 같은 노드들을 가지고 있다. *는 0개 이상이란 뜻 -->
   <!ELEMENT goods (#PCDATA)>
  <!ELEMENT qty (#PCDATA)><!--pcdata: 값을 가지고 있다. -->
  <!ELEMENT cost (#PCDATA)>
  <!ELEMENT amount (#PCDATA)>
  <!ELEMENT filename (#PCDATA)>
  <!ELEMENT qtysum (#PCDATA)>
  <!ELEMENT amountsum (#PCDATA)>
<!ATTLIST cart id CDATA #REQUIRED> <!-- card id가 존재하는데 #REQUIRED로 (꼭필요하다)-->

-------------------------------------------------------------------------------------------
다음과 같이 설정한다.


3. 실제 UI가 발생할 xsl파일을 생성한다.
cart.xsl
-------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="euc-kr" ?>
 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method = "html" indent="yes" encoding="euc-kr" />
  <xsl:template match="cartlist"> <!-- dtd문서에서 cartlist를 연결시켜줌 -->
<!-- 가장 최상위 eliement를 설정해 준다. -->
    <table border="0" cellpadding="0" cellspacing="1" bgcolor="#c0c0c0">
     <tr height="24" bgcolor="#f0f0f0">
       <td width="50" align="center"><span style="font:10pt"><b>선택</b></span></td>
       <td width="100" align="center"><span style="font:10pt"><b>상품명</b></span></td>
       <td width="52" align="center"><span style="font:10pt"><b>수량</b></span></td>
       <td width="90" align="center"><span style="font:10pt"><b>구입단가</b></span></td>
       <td width="95" align="center"><span style="font:10pt"><b>구입금액</b></span></td>
     </tr>
     <xsl:for-each select="cart">
   <tr height="24" bgcolor="#ffffff">
    <td align="center">
     <span style="font:10pt">
        <input type="checkbox" name="items" value="{filename}"/> 
     </span>
    </td>
   <td align="center">
      <a href="javascript:cartInfo('{filename}','{qty}','{cost}','{amount}')">
       <span style="font:10pt"><xsl:value-of select="goods"/></span>
      </a>  
    </td>
      
    <td align="center"><span style="font:10pt"><xsl:value-of select="qty"/></span></td>
    <td align="right"><span style="font:10pt;padding-right:5px"><xsl:value-of select="cost"/></span></td>
    <td align="right"><span style="font:10pt;padding-right:5px"><xsl:value-of select="amount"/></span></td>
   </tr>   
  </xsl:for-each>
   <tr height="24" bgcolor="#f0f0f0">
    <td align="center"><input type="button" value="삭제" onclick="delproc()"/></td>
    <td align="center"><span style="font:10pt"><b>항목별 합계</b></span> </td>
    <td align="center">
       <span style="font:10pt; color:#ff795a">
      <xsl:value-of select="qtysum"/>
       </span>
    </td>
    <td align="center"><span style="font:10pt">-</span> </td>
    <td align="right">
       <span style="font:10pt; color:#ff795a;padding-right:9px">
       <xsl:value-of select="amountsum"/>
       </span>
    </td>
   </tr>
 </table>
  </xsl:template>
</xsl:stylesheet>
-------------------------------------------------------------------------------------------
- for-each : 반복되는 데이터를 가져온다.
value-of select = xml문서의 다음과 같은 이름의 데이터를 가져온다.