XSLT - 웹을 위한 네이티브, 무설정 빌드 시스템
(github.com/pacocoursey)- XSLT를 웹 브라우저에서 실행되는 클라이언트 측 빌드 시스템처럼 사용해 XML 데이터를 HTML로 변환하고, 정적 사이트 생성기의 복잡성을 줄일 수 있음
- 일반적인 정적 사이트는
.json,.md,.txt같은 데이터와 Hugo, Next.js, Astro 같은 빌드 시스템, 정적 HTML 출력으로 구성되지만, 큰 프레임워크는 단순한 Markdown 블로그에도 과한 복잡성을 만들 수 있음 - HTML과 CSS만 쓰려 하면 여러 페이지의 헤더와 푸터를 직접 복사해야 하고, HTML import는 없으며 Web Component는 JavaScript 엔진이 필요하다는 제약이 있음
- XML 문서에
<?xml-stylesheet type="text/xsl" href="blog.xsl"?>를 추가하고 XSLT 템플릿을 작성하면 브라우저가 방문 시점에 HTML 출력을 생성할 수 있음 - 이 방식은 JavaScript 없이 정적 파일로 배포할 수 있지만, 모든 것을 대체하는 완벽한 해법은 아니며 웹 개발 도구함에 추가할 수 있는 또 다른 선택지임
정적 사이트 빌드의 복잡성
- 일반적인 정적 웹사이트 제작 흐름은 데이터, 빌드 시스템, 정적 HTML 출력으로 나뉨
- 데이터는
.json,.md,.txt같은 파일로 저장됨 - 빌드 시스템 예시는 Hugo, Next.js, Astro 등이 있음
- 최종 결과물은 정적 HTML임
- 데이터는
- 프레임워크를 제거하고 단순한 HTML과 CSS만 쓰고 싶어도, 페이지가 많아지면 공통 헤더와 푸터를 계속 복사해야 함
- 대안으로 떠올릴 수 있는 선택지는 각각 제약이 있음
- HTML import는 존재하지 않음
- Web Component는 JavaScript가 필요하고, 따라서 JavaScript 엔진이 필요함
브라우저를 빌드 시스템으로 쓰는 발상
- 웹 브라우저는 이미
text/html,text/markdown,application/xml같은 여러 형식을 이해할 수 있음 - 브라우저를 데이터에서 HTML을 만드는 시스템으로 쓰면, 별도 빌드 도구 없이 웹 표준 기반 흐름을 만들 수 있음
- RSS 피드를 더 보기 좋게 표시하려는 과정에서 XSLT를 XML 문서용 스타일시트로 사용할 수 있음을 발견함
- XML은 HTML과 비슷하게 보이지만 웹 데이터에만 한정되지 않는 데이터 표현 방식이며, XML spec을 통해 확인할 수 있음
XML에서 HTML로 변환하는 방식
- XML 문서는 블로그 글 같은 데이터를 담을 수 있음
<?xml version="1.0"?>
<blog>
<post id="42" publishedAt="2025-06-26">
<title>Hello XSLT</title>
<tags>…</tags>
</post>
</blog>
- XML 문서에 XSL 스타일시트를 연결하는 선언을 추가할 수 있음
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="blog.xsl"?>
<blog>
<post id="42" publishedAt="2025-06-26">
<title>Hello XSLT</title>
<tags>…</tags>
</post>
</blog>
- XSLT 템플릿은 XML 입력을 받아 HTML 구조를 출력함
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
<html>
<head> … </head>
<body> … </body>
</html>
</xsl:template>
</xsl:stylesheet>
- XSLT는
(XML) => HTML형태로 볼 수 있으며, 반복문, 변수, import 같은 빌드 시스템 기능을 제공함 - 부모 XML 문서의 데이터를 XSLT에서 가져와 동적으로 출력할 수 있음
<head>
<xsl:value-of select="title" /> | Blog
</head>
실행과 배포 방식
- XML 파일을 브라우저로 열면 XSLT 변환을 실행할 수 있음
open blog.xml -a Safari
- 모든 웹 브라우저는 페이지 방문 시 XSLT 변환을 지원하고, 변환 결과 HTML을 표시함
- 이 방식은 사용자의 컴퓨터에서 실행되는 클라이언트 측 빌드 시스템처럼 동작함
- 정적 파일 배포가 쉽고 JavaScript 없이 동작함
한계와 위치づけ
- 블로그 데이터를 JSON이 아니라 XML로 저장해야 하지만, XML은 HTML처럼 보이고 파싱하기 쉬우며 유연하고 웹에서 네이티브로 지원됨
- XSLT 방식은 완벽하지 않고 모든 것을 대체하지는 않음
- 오래된 웹 표준, 명세, 브라우저 기능을 활용해 단순한 정적 웹사이트 제작에 쓸 수 있는 또 다른 도구가 됨
댓글과 토론
Hacker News 의견들
-
XML 템플릿에 XSLT를 많이 쓰던 회사에서 일한 적이 있는데, 좋지 않았고 가능했다면 아마 이전했을 것임
새 표준이 있어도 XSLT 1.0이 여전히 지배적이고, 최신 표준에 비해 제한적이고 이상함
XSLT 템플릿의 성능 문제를 푸는 건 지옥에 가까움. 튜링 완전한 함수형 스타일 언어인데 성능이 많이 추상화되어 있어, 대부분 문서에서는 잘 돌던 템플릿이 100행짜리 표 하나에서 폭발하기도 함. 알고 보니 표 처리 템플릿이 O(N^2) 이상이고, 각 행마다 XPath가 다시 O(N) 이상일 수도 있어 최적화 방법도 뚜렷하지 않았음. 기억으로는 문서 하나를 XSLT로 처리하는 데 7분 넘게 걸렸음
JS에도 다른 문제는 있겠지만, 알고리즘 복잡도 문제를 해결 못 하는 건 그중 하나가 아님- XSLT/XPath는 XSLT 1.0 이후로 발전했음
이제 key(색인) 같은 기능으로 처리를 크게 빠르게 할 수 있고, Saxon 같은 좋은 XSLT 구현도 성능 면에서 확실히 도움이 됨
XML을 다른 형식으로 변환할 때는 로직을 구조화할 수 있어서 XSLT가 꽤 편리함 - “XSLT 1.0이 여전히 지배적”이라는 게 어디서 그런지 모르겠음
2013년에 XSLT를 많이 쓰고 있었는데, 그때 이미 1.0은 어디서 봐도 완전히 죽은 상태였음. Saxon은 XSLT 2용으로 무료였고 훌륭했음
거대한 문서와 작은 문서 다수를 모두 변환했지만 성능 문제는 전혀 없었음 - XSLT는 쉽지 않음. 비유하자면 환각 버섯 먹은 Prolog 같고 학습 곡선이 가파름
익히고 나면 스도쿠를 푼 듯한 만족감은 주지만, 보통은 목표 달성에 훨씬 적은 도구면 충분해서 빌드나 템플릿의 표준 접근법이 되기는 어려움
게다가 XML도 모두가 좋아하는 형식은 아님 - XSLT는 긴 원본 XML을 처리하는 게 당연하던 시대에 만들어진 것 같은데, 중첩 반복문이 터지는 건 너무 뻔해 보여서 이상함
- Saxon의 상용 버전을 쓰는지 궁금함. 비싸지 않고, 지원 기능과 성능을 생각하면 가치가 있다고 봄
기억이 맞다면 꽤 영리한 최적화도 해줬음
- XSLT/XPath는 XSLT 1.0 이후로 발전했음
-
꽤 무리한 추측일 수 있지만, 1990~2000년대에는 브라우저가 제각각이라서 같은 동작을 만들려고 JS를 쓰기 시작했고, 사실 필요했던 건 좋은 CSS 스타일과 일관된 동작이었음
시간이 지나며 브라우저들은 비슷하게 동작하기 시작했지만, 이미 모든 브라우저에서 페이지를 같아 보이게 하는 프레임워크에 익숙해졌고, JSON 데이터를 렌더링하는 패러다임으로 바뀌었음
지금 기술 수준이면 서버가 생성하는 구식 웹 페이지도 충분히 감당 가능하고, 발자국이 작고 더 빠르며 메모리도 덜 씀
최근 레거시 시스템 이전을 하면서 2000년대식 “HTTP 요청마다 한 페이지” 구조를 봤는데, 추가/삭제 같은 모든 동작이 새로고침을 요구해도 React 시스템보다 훨씬 빨랐음. 인터넷은 빨라졌고, 휴대폰 메모리는 JS 프레임워크가 낭비하고 있으며, 백엔드는 여전히 CRUD, 페이지네이션, 트랜잭션이 대부분임- AJAX와 DOM 갱신은 단순히 “더 빠르게” 만들려고 들어간 게 아니라, 문서를 표시하던 웹 사이트/웹 문서 패러다임을 바꾸려고 들어간 것임
HN처럼 단순한 곳에서는 전체 페이지 새로고침이 잘 맞고, JS 프레임워크 대신 단순한 웹사이트로 충분한 사례도 많음
하지만 모두가 전체 페이지 새로고침으로 돌아갈 수 있다는 건 맞지 않음. 실제 웹 애플리케이션 중에는 전체 새로고침이 끔찍한 사용자 경험이 되는 경우가 있음
대체로 웹사이트, 웹 문서, 웹 폼은 전체 새로고침으로도 가능하지만, 복잡한 것을 보여주고 조작해야 하는 웹 애플리케이션에는 맞지 않음 - 그 연표는 맞지 않는 것 같음. JS는 동작 표준화보다는 초기에 상호작용성을 위해 쓰였고, DHTML과 나중의 AJAX가 그 예였음
당시에는 사용자 에이전트 감지와 각종 quirks 순서에 기대어 레이아웃을 맞췄고, JS가 레이아웃 관련 요소에 쉽게 접근할 수 있었던 것 같지도 않음
CSS도 일관성을 바로 가져오지는 못했음. 기능이 갖춰진 뒤에도 엉망이었고, CSS Zen Garden에 모두 감탄하면서도 실제 코드는 테이블로 짜던 시절이었음
프레임워크가 “일관된 외형”에 큰 영향을 줬는지도 모르겠음. jQuery를 벗어날 즈음에는 이미 CSS가 외형을 담당하고 있었음 - .NET/Kestrel/SQLite 스택으로 서버 사이드 렌더링 응답을 최대 약 4밀리초 안에 뽑아낼 수 있음. 릴리스 빌드에서는 평균 응답 시간이 수백 마이크로초 단위임
페이지마다 여러 쿼리를 날리고, 뷰 전용 응답 형태를 만들기 위해 복잡한 조인도 많이 쓰는 조건임. HTML 문자열에 보간하기 전에 데이터를 맞는 형태로 가져오면 10만 행짜리 표 같은 경계 상황에서 성능에 큰 도움이 됨
경험상 HTML 템플릿 엔진과 데이터베이스가 가까울수록 좋음. 결국 구조화된 DOM도 클라이언트에 보내야 하는 바이트 스트림일 뿐임
StringBuilder와 똑똑한 SQL 쿼리면 되는 곳에 정교한 AST/파서 접근을 고민하면서, 무의미하고 자기 목적적인 산업이 생겼다고 봄. 반대 논리는 대체로 개발자가 HTML 이스케이프 함수를 제대로 못 쓴다고 보는 보안 감시자식 태도로 귀결됐음 - 현재 기술로 서버 생성 구식 웹 페이지를 감당할 수 있다는 건 지연 시간이 높은 인터넷 연결에서는 예외가 있음: https://news.ycombinator.com/item?id=44326816
- AJAX와 DOM 갱신은 단순히 “더 빠르게” 만들려고 들어간 게 아니라, 문서를 표시하던 웹 사이트/웹 문서 패러다임을 바꾸려고 들어간 것임
-
2000년대 엔터프라이즈 XML의 비대함 때문에 기술이 낡아 보이고 모두가 더 “깔끔한” JSON으로 몰린 게 아쉬움
XSLT와 XPath는 매우 성숙했고, 다른 형식에서 아직도 겪는 많은 문제를 이미 해결해줬음
예전에는 PHP 스트림 래퍼와 XSLT include를 남용했던 좋은 기억도 있음
오래된 편견일 수도 있지만, 브라우저가 로컬에서 처리하게 두는 건 아직 조금 불안함. 예전에는 호환성 지뢰밭이었기 때문임- 오래됐지만 JSON에서 XML의 “기본” 몇 가지가 아직 그리움. 우선 제대로 된 표준화 기구가 있었음
XML 쪽의 스키마 같은 것들은 훨씬 잘 정의되어 있었고, JSON 쪽이 따라잡는 데 거의 10년이 걸렸다고 느껴짐
마지막으로 제대로 다뤘던 XML 기술은 EXI였는데, XML 문서를 압축된 이진 데이터 스트림으로 바꾸는 전송 방식이었음. 데이터 구조를 ASCII로 바꾸고 압축해서 HTTP로 보내고 다시 되돌리는 건 좀 우스운 일이기 때문임
지금은 protobuf 계열이 더 인기 있지만, XML이 계속 남아 있었다면 서로 맞물리는 호환 표준들의 세계가 됐을 수도 있음. 반면 protobuf/gRPC와 JSON API 사이에는 단단한 장벽이 있는데, 어쩌면 그게 더 나은지도 모르겠음 - XML은 괜찮음. 좀 장황하지만 YAML에 비해 정밀함과 표현력이 마음에 듦
XPath도 나쁘지 않음. 문법을 다 기억하기는 어렵지만 조금 실험하면 대체로 원하는 곳에 도달함
XSLT는 완전히 미친 헛소리라 불타 없어져야 함 - 게임 Rimworld는 모든 게임 설정 데이터를 XML에 저장하고, 모딩에 XPath를 쓰는데 정말 좋음
데이터의 비교적 안정적인 로컬 수정을 가능하게 하는 조합으로 XML + XPath는 심각하게 저평가되어 있음. XML이 “구식”이라는 평판이 있어서인지 다른 게임에서는 잘 못 봤지만, 이 용도에는 매우 견고한 시스템임
https://rimworldwiki.com/wiki/Modding_Tutorials/PatchOperati... - XML은 원래 SGML의 단순화된 부분집합으로, 웹에서 마크업을 전달하고 브라우저의 마크업 어휘와 기능을 발전시키려던 것이었음
하지만 웹 열풍이 커지자 W3C와 MS가 SOAP, WS-* 같은 것들을 만들었고, XSLT를 포함해 XML 기반 프로그래밍 언어도 여럿 생겼음
HN 사람들에게 말하면 안 되겠지만, XSLT는 원래 Scheme이었는데 반드시 XML이어야 했고, JavaScript가 Java 이름을 빌려야 했던 것과 같은 광기의 시대였음 - XPath는 모든 쿼리의 모든 부분에 네임스페이스를 꼼꼼하게 붙이지 않아도 됐다면 좋았을 것임
- 오래됐지만 JSON에서 XML의 “기본” 몇 가지가 아직 그리움. 우선 제대로 된 표준화 기구가 있었음
-
요즘은 피드를 꾸미는 데 XSLT를 씀
예를 들면 https://susam.net/feed.xml와 https://susam.net/feed.xsl임- 이걸 보니 블로그가 그냥 RSS 피드이면 안 되는 이유가 뭔지 생각하게 됨
- XML이 이런 걸 할 수 있다는 사실을 항상 잊음. 왠지 모르게 이상하게 느껴짐
- 같은 방식으로 하고 있음: https://adithyanair.com/feed.xml
-
19살에 전문 소프트웨어 엔지니어로 처음 맡은 프로젝트 중 하나가 회사에서 산 Google Search Appliance 두 대를 커스터마이즈하는 일이었음
회사는 거대한 CIFS 문서 저장소를 전문 검색할 수 있으면 사업 개발 프로세스가 개선될 거라 보고, CentOS와 Google식 Python이 올라간 노란 전면의 Dell 서버 랙에 수십만 달러를 썼음
2011년 무렵 XHTML이 유행이었고, GSA는 백엔드에서 XML로 제공한 검색 결과를 XSLT로 XHTML로 바꾸는 방식이었음
기본 템플릿을 가져와 렌더링된 ColdFusion 애플리케이션 페이지, StackOverflow, W3Schools 튜토리얼에서 훔친 자산과 마크업으로 회사 인트라넷 포털 비슷한 괴물을 만들었음
이후 LinkedIn에서 여러 DoD 계약업체가 “XML 전문성”을 보고 문서 현대화 프로젝트에 참여하라고 연락해 왔고, 이 경험은 이력서에서 빼야 한다는 걸 빨리 배웠음
JSON 응답에서 역직렬화한 TypeScript 인터페이스 배열을 JSX로 반복하며 한숨쉴 때, XSLT로 같은 일을 하던 나를 떠올리면 됨 -
XML이 장황하다고 불평하는 사람이 많고 멀리서 보면 복잡해 보이지만, XML 기반으로 좋은 파일 형식을 만들고 DTD로 검증한 뒤 필요하면 XSLT로 사람이 읽기 좋게 포맷할 수 있다는 점이 좋음
XML은 텍스트 기반 파일 형식의 C++ 같음. 성숙했고, 배터리가 포함되어 있으며, 강력하고, 원하면 어떤 언어에서도 쓸 수 있음
오래되고 성숙한 언어들이 각자의 기묘함 때문에 욕먹듯 XML을 욕하는 것도 유행이 되어버렸음. 용도에 맞지 않으면 안 쓰면 되지만, 괴물 취급할 건 아님- 왜 DTD를 쓰고 XSD는 안 쓰는지 궁금함
-
2000년대 초 XML과 XSLT가 얼마나 멀리 갔는지 보여주는 예로, 예전에 일하던 회사는 XML을 회선 속도로 파싱하고 XSLT를 칩에서 네이티브로 처리하는 ASIC을 만들었음
인터넷의 미래가 전부 XML/XSLT일 거라고 예상했기 때문임. Intel이 그 회사를 인수했고, 내부 기술은 SSE 가속기로 들어갔음- 그 길로 갔다면 웹사이트가 얼마나 빠르게 렌더링됐을지 상상하게 됨
- IBM은 아직도 그 설명과 대략 맞는 하드웨어인 DataPower Gateway를 팔고 있음
-
“XSLT가 브라우저에서 네이티브로 동작한다”는 마법이 뭔지 놀라움
마지막으로 XSLT를 쓴 건 20년 전쯤이지만, 그때는 몇 년 동안 아주 많이 썼음. 당시에는 작동시키려면 거대하고 흔들리는 엔터프라이즈 Java 탑이 필요해서 XSLT 자체의 우아함을 깎아먹었음
그런데 XSLT가 실제로 브라우저에서 동작한다면, 어디서나 호스팅 가능한 정적 템플릿이라는 성배가 계속 코앞에 있었던 셈임- 브라우저는 XSLT v1.0만 지원하고, 듣기로는 폐기 얘기도 있었음
차라리 v3 지원이 들어오면 네이티브 템플릿 지원으로 정적 웹페이지를 제공하기 쉬워질 것 같음 - “거대하고 흔들리는 엔터프라이즈 Java 탑”까지는 아니었음. Tomcat과 몇몇 Apache 라이브러리로 잘 썼음
CMS는 내장 HTML이 들어간 XML 파일을 뱉었고 캐시가 매우 잘 됐음. 개인화와 HTML/JS 렌더링은 서버 쪽에서 캐싱 프록시와 함께 처리했음
XSL 변환은 캐시 뒤에서 실행됐고 많은 트래픽을 따라갈 만큼 빨랐음. 여기서 XML의 목적은 준비된 HTML은 블롭으로 넣고, 개인화가 필요한 부분만 XML 태그로 두는 것이었음
최종 변환은 꽤 빨랐고, 핵심은 XSL 변환기의 출력을 전체 메모리 버퍼에 담지 않고 응답 출력 스트림으로 바로 흘리는 것이었음. 큰 응답에서는 지금도 좋은 기법인데, 많은 프레임워크가 기본값으로 메모리 버퍼링을 택해서 놓치는 부분임
요즘은 물론 wasm으로 브라우저에서 원하는 걸 돌릴 수 있음. 하지만 당시 JavaScript는 엉망이었고, 디자이너는 잘해봐야 Photoshop 파일을 넘겨줬음. 그걸 프레임과 테이블로 잘라야 했고, Google Maps와 Gmail이 막 나왔던 시기에 Netscape와 Internet Explorer를 모두 지원하며 꽤 JavaScript-heavy한 CMS UI를 만들고 있었음 - 2008년에 브라우저에서 XSLT를 쓰는 사이트를 다뤘는데, 지원 자체는 2000년대 초까지 거슬러 올라가는 것 같음
- XSLT는 동작하지만, 브라우저들이 모두 오래된 명세 버전에 묶여 있는 것 같음
Firefox에는 특히 성가신 버그가 있는데, 문서 안의 HTML을 실제 DOM으로 렌더링하려고disable-output-escaping이 필요할 때 제대로 동작하지 않고 원시 HTML 텍스트로 렌더링됨 - 엔터프라이즈 Java 탑이 필요했다는 건 이해가 안 됨. classic ASP에서 VBScript 세 줄 정도로 XML을 변환했음
- 브라우저는 XSLT v1.0만 지원하고, 듣기로는 폐기 얘기도 있었음
-
오래전 아주 먼 디스토피아 프로젝트에서, 팀이 Java 개발을 빠르게 바뀌는 워크북과 병렬로 조율할 수 없을 거라 비관한 사람이 해결책을 냈음
Excel로 작성된 워크북을 Visual Basic이 XML로 만들고, 그 XML에 정의된 Struts 액션을 처리할 Java 클래스를 XSLT 파일들이 자동 생성하는 구조였음
https://raganwald.com/2008/02/21/mouse-trap.html
HN 토론: https://news.ycombinator.com/item?id=120379 · https://news.ycombinator.com/item?id=947952