XQuery FLWOR를 활용한 HTML 페이지 생성 완벽 가이드

다음 예제들은 BaseX, eXist-db, Saxon 또는 온라인 편집기에서 바로 실행 가능하며, 실행 결과로 완전한 HTML 파일이 생성됩니다. 브라우저에서 바로 열어 확인할 수 있습니다.

공통 XML 데이터

<!-- books.xml -->
<bookstore>
  <book category="web" year="2020">
    <title>XQuery 실전</title>
    <author country="CN">김철수</author>
    <author country="CN">이영희</author>
    <price>88.00</price>
  </book>
  <book category="web" year="2003">
    <title>XQuery Kick Start</title>
    <author country="US">James McGovern</author>
    <price>49.99</price>
  </book>
  <book category="cooking" year="2005">
    <title>Everyday Italian</title>
    <author country="IT">Giada</author>
    <price>30.00</price>
  </book>
  <book category="children" year="2005">
    <title>Harry Potter</title>
    <author country="UK">J.K. Rowling</author>
    <price>29.99</price>
  </book>
</bookstore>

1. 기본 HTML 페이지 생성 (추천)

xquery version "3.1";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "html";
declare option output:html-version "5.0";
declare option output:include-content-type "yes";

<html>
  <head>
    <title>내 서점 - XQuery 생성</title>
    <style>
      table {{
        border-collapse: collapse;
        width: 100%;
      }}
      th, td {{
        border: 1px solid #2980b9;
        padding: 10px;
        text-align: left;
      }}
      th {{
        background-color: #2980b9;
        color: white;
      }}
      tr:nth-child(even) {{
        background-color: #f0f0f0;
      }}
      .web {{
        background-color: #e0f0ff;
      }}
      .price-high {{
        color: red;
        font-weight: bold;
      }}
    </style>
  </head>
  <body>
    <h1>도서 목록 (총 {count(doc("books.xml")//book)}권)</h1>
    
    <table>
      <thead>
        <tr>
          <th>번호</th>
          <th>제목</th>
          <th>저자</th>
          <th>분류</th>
          <th>출판년도</th>
          <th>가격</th>
        </tr>
      </thead>
      <tbody>
      {
        for $book at $i in doc("books.xml")//book
        let $authors := string-join($book/author, ", ")
        order by xs:decimal($book/price) descending
        return
          <tr class="{$book/@category}">
            <td>{$i}</td>
            <td>{$book/title/text()}</td>
            <td>{$authors}</td>
            <td>{$book/@category/string()}</td>
            <td>{$book/@year/string()}</td>
            <td class="{if ($book/price > 50) then 'price-high' else ''}">
              ₩{$book/price/text()}
            </td>
          </tr>
      }
      </tbody>
    </table>
    
    <p style="margin-top:20px; color:gray;">
      이 페이지는 XQuery FLWOR로 생성됨: {current-dateTime()}
    </p>
  </body>
</html>

2. Bootstrap 5 기반 반응형 테이블 (실무 활용)

xquery version "3.1";
declare option output:method "html";
declare option output:html-version "5";

<html lang="ko">
  <head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <title>XQuery 부트스트랩 도서 테이블</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
  </head>
  <body class="bg-light">
    <div class="container py-4">
      <h1 class="mb-4">도서 관리 시스템 <small class="text-muted">— XQuery 기반</small></h1>
      
      <div class="row mb-3">
        <div class="col">
          <span class="badge bg-primary fs-6">총 {count(doc("books.xml")//book)}권</span>
          <span class="badge bg-success ms-2">평균 가격 ₩{format-number(avg(doc("books.xml")//price), '#.00')}</span>
        </div>
      </div>

      <div class="table-responsive">
        <table class="table table-hover align-middle">
          <thead class="table-dark">
            <tr>
              <th>#</th>
              <th>제목</th>
              <th>저자</th>
              <th>분류</th>
              <th>가격</th>
              <th>액션</th>
            </tr>
          </thead>
          <tbody>{
            for $book at $index in doc("books.xml")//book
            let $writers := string-join($book/author ! concat(., '(', @country, ')'), ', ')
            order by $book/title
            return
              <tr>
                <th scope="row">{$index}</th>
                <td><strong>{$book/title/text()}</strong></td>
                <td>{$writers}</td>
                <td><span class="badge bg-info">{$book/@category/string()}</span></td>
                <td>
                  <span class="text-{if ($book/price > 60) then 'danger' else 'success'}">
                    ₩{$book/price/text()}
                  </span>
                </td>
                <td>
                  <button class="btn btn-sm btn-outline-primary">상세</button>
                  <button class="btn btn-sm btn-outline-warning">수정</button>
                </td>
              </tr>
          }</tbody>
        </table>
      </div>
    </div>
  </body>
</html>

3. 다중 페이지 생성 및 내비게이션

(: index.html + 카테고리별 페이지 생성 :)
let $categories := distinct-values(doc("books.xml")//book/@category)

return (
  (: 1. 메인 페이지 :)
  file:write("/output/index.html",
    <html>...(위 Bootstrap 예제)...</html>
  ),
  
  (: 2. 카테고리별 서브 페이지 :)
  for $cat in $categories
  let $books := doc("books.xml")//book[@category = $cat]
  return file:write(concat("/output/", $cat, ".html"),
    <html>
      <head><title>{$cat} 카테고리 도서</title></head>
      <body>
        <h1>{$cat} 분야 도서 (총 {count($books)}권)</h1>
        <ul>{
          for $book in $books
          return <li>{$book/title/text()} - ₩{$book/price}</li>
        }</ul>
        <a href="index.html">메인으로</a>
      </body>
    </html>
  )
)

4. HTML 파일 저장 (BaseX 전용)

let $html := 
<html>......(위 예제 중 하나)</html>

return file:write-binary("C:/output/my-books.html", $html)

핵심 장점

  • 서버에서 100% 생성, 프론트엔드 프레임워크 불필요
  • 데이터와 표현 완전 분리
  • 복잡한 정렬, 그룹화, 페이징, 조건부 하이라이트 지원
  • XML/JSON 데이터 소스와 즉시 연동 가능
  • 금융, 출판, 정부 보고서 시스템에서 널리 사용

위 예제를 .xq 파일로 저장하고 BaseX에서 실행한 후 "Save" 버튼을 클릭하면 완벽한 HTML 파일이 생성됩니다.

태그: XQuery FLWOR HTML BaseX bootstrap

7월 21일 02:38에 게시됨