Ver3.5 ๐๏ธ XML ยท XSLT ยท XPath๋ฅผ ํ์ฉํ ๊ตฌ์กฐํ๋ ๋ฌธ์ ์ฒ๋ฆฌ์ ๋ณํ ๊ธฐ์

๐๏ธ XML ยท XSLT ยท XPath๋ฅผ ํ์ฉํ ๊ตฌ์กฐํ๋ ๋ฌธ์ ์ฒ๋ฆฌ์ ๋ณํ ๊ธฐ์
๋ฐ์ดํฐ๋ฅผ ์์ ์์ฌ๋ก ์๋ฆฌํ๋ XML ํธ๋ฆฌ์ค์ ์ธ๊ณ๋ก ํจ๊ป ๋ ๋๋ณด์! ๐
์์งํ ๋งํ๋ฉด, ์ฒ์ XML์ด๋ผ๋ ๋จ์ด๋ฅผ ๋ค์์ ๋ "๋ ๋ญ ์ฝ์์ผ..." ์ถ์๋ ์ฌ๋ ์! โ
๊ทผ๋ฐ ์๊ณ ๋ณด๋ฉด XML์ ์ฐ๋ฆฌ ์ผ์ ๊ณณ๊ณณ์ ์จ์ด์๋ ์์ฒญ๋ ์น๊ตฌ์ผ.
์๋๋ก์ด๋ ์ฑ ์ค์ ํ์ผ, ๋ง์ดํฌ๋ก์ํํธ ์คํผ์ค ๋ฌธ์(.docx, .xlsx), RSS ํผ๋, ์น ์๋น์ค API ์๋ต๊ฐ...
์ ๋ถ XML ๊ธฐ๋ฐ์ด๊ฑฐ๋ XML์์ ํ์๋ ํ์์ด๊ฑฐ๋ . ๐ฒ
XML(eXtensible Markup Language)์ 1998๋
W3C์์ ํ์คํํ ๋งํฌ์
์ธ์ด์ผ.
HTML์ด "์ด๋ป๊ฒ ๋ณด์ฌ์ค๊น"์ ์ง์คํ๋ค๋ฉด, XML์ "๋ฐ์ดํฐ๋ฅผ ์ด๋ป๊ฒ ๊ตฌ์กฐํํ ๊น"์ ์ง์คํด.
ํ๊ทธ๋ฅผ ๋ง์๋๋ก ๋ง๋ค ์ ์์ด์ "ํ์ฅ ๊ฐ๋ฅํ(eXtensible)" ๋งํฌ์
์ธ์ด๋ผ๊ณ ๋ถ๋ฅด๋ ๊ฑฐ์ง.
| ํน์ง | ์ค๋ช |
|---|---|
| ์๊ธฐ ์์ ์ (Self-describing) | ํ๊ทธ ์ด๋ฆ ์์ฒด๊ฐ ๋ฐ์ดํฐ์ ์๋ฏธ๋ฅผ ์ค๋ช ํจ |
| ํ๋ซํผ ๋ ๋ฆฝ์ | OS, ์ธ์ด, ์์คํ ์ ์๊ด์์ด ๋ฐ์ดํฐ ๊ตํ ๊ฐ๋ฅ |
| ๊ณ์ธต ๊ตฌ์กฐ(Tree Structure) | ๋ถ๋ชจ-์์ ๊ด๊ณ๋ก ๋ฐ์ดํฐ๋ฅผ ์ค์ฒฉ ํํ |
| ์ ๋์ฝ๋ ์ง์ | ํ๊ธ, ์ผ๋ณธ์ด, ์๋์ด ๋ฑ ๋ค๊ตญ์ด ์๋ฒฝ ์ง์ |
| ํ์ฅ์ฑ | ์ฌ์ฉ์ ์ ์ ํ๊ทธ๋ก ์ด๋ค ๋๋ฉ์ธ์๋ ์ ์ฉ ๊ฐ๋ฅ |
XML ๋ฌธ์๋ ํฌ๊ฒ ํ๋กค๋ก๊ทธ(Prolog)์ ๋ฌธ์ ์์(Document Element)๋ก ๋๋์ด.
์ค์ ์ฝ๋๋ฅผ ๋ณด๋ฉด์ ์ดํดํด๋ณด์!
<?xml version="1.0" encoding="UTF-8"?>
<!-- ์ด๊ฑด XML ์ ์ธ๋ถ (ํ๋กค๋ก๊ทธ) -->
<๋์๋ชฉ๋ก>
<๋์ id="001" ์นดํ
๊ณ ๋ฆฌ="ํ๋ก๊ทธ๋๋ฐ">
<์ ๋ชฉ>XML ๋ง์คํฐํ๊ธฐ</์ ๋ชฉ>
<์ ์>ํ๊ธธ๋</์ ์>
<์ถํ๋
๋>2024</์ถํ๋
๋>
<๊ฐ๊ฒฉ ํตํ="KRW">28000</๊ฐ๊ฒฉ>
</๋์>
<๋์ id="002" ์นดํ
๊ณ ๋ฆฌ="์น๊ฐ๋ฐ">
<์ ๋ชฉ>XSLT ์ค์ ๊ฐ์ด๋</์ ๋ชฉ>
<์ ์>๊น์ฒ ์</์ ์>
<์ถํ๋
๋>2023</์ถํ๋
๋>
<๊ฐ๊ฒฉ ํตํ="KRW">32000</๊ฐ๊ฒฉ>
</๋์>
</๋์๋ชฉ๋ก>
์ ์ฝ๋์์ ๋ณผ ์ ์๋ฏ์ด, XML์ ํ๊ทธ(Tag), ์์ฑ(Attribute), ํ
์คํธ ์ฝํ
์ธ ๋ก ๊ตฌ์ฑ๋ผ.
๊ทธ๋ฆฌ๊ณ ๋ฐ๋์ ํ๋์ ๋ฃจํธ ์์(<๋์๋ชฉ๋ก>)๊ฐ ์์ด์ผ ํ๊ณ , ๋ชจ๋ ํ๊ทธ๋ ๋ฐ๋์ ๋ซํ์ผ ํด.
Well-formed(ํ์์ด ์ฌ๋ฐ๋ฅธ): XML ๋ฌธ๋ฒ ๊ท์น์ ์งํจ ๋ฌธ์ (ํ๊ทธ ๋ซ๊ธฐ, ๋์๋ฌธ์ ์ผ์น ๋ฑ)
Valid(์ ํจํ): DTD๋ XML Schema์ ๋ฐ๋ผ ๊ตฌ์กฐ๊น์ง ๊ฒ์ฆ๋ ๋ฌธ์
Well-formed๋ ํ์, Valid๋ ์ ํ์ด์ง๋ง ์๊ฒฉํ ๋ฐ์ดํฐ ๊ตํ ์์ Valid๋ ์ค์ํด!
XML ๋ฌธ์๋ ์ฌ๋ฌ ์ข ๋ฅ์ ๋ ธ๋๋ก ๊ตฌ์ฑ๋ ํธ๋ฆฌ์ผ. ๊ฐ ๋ ธ๋ ํ์ ์ ์์์ผ XPath๋ฅผ ์ ๋๋ก ์ธ ์ ์์ด!
<์ ๋ชฉ>...</์ ๋ชฉ>
๊ฐ์ฅ ๊ธฐ๋ณธ ๋จ์
id="001"
์์์ ๋ฉํ์ ๋ณด
ํ๊ทธ ์ฌ์ด์
์ค์ ํ ์คํธ ๊ฐ
<!-- ์ฃผ์ -->
์ฒ๋ฆฌ์ ๋ฌด์๋จ
XPath(XML Path Language)๋ XML ๋ฌธ์ ๋ด์์ ์ํ๋ ๋
ธ๋๋ฅผ ์ฐพ์๊ฐ๋ ๊ฒฝ๋ก ํํ ์ธ์ด์ผ.
๋ง์น ํ์ผ ์์คํ
์ ๊ฒฝ๋ก์ฒ๋ผ "/" ์ฌ๋์๋ก ๊ณ์ธต์ ํํํ๋๋ฐ, ํจ์ฌ ๊ฐ๋ ฅํ ํํฐ๋ง ๊ธฐ๋ฅ๊น์ง ๊ฐ์ถ๊ณ ์์ด.
XPath๋ XSLT์ ํต์ฌ ์์ง์ด๊ธฐ๋ ํ๊ณ , ์น ์คํฌ๋ํ, ํ
์คํธ ์๋ํ(Selenium) ๋ฑ์๋ ๋๋ฆฌ ์ฐ์ฌ. ๐บ๏ธ
/* ์ ๋ ๊ฒฝ๋ก (๋ฃจํธ๋ถํฐ ์์) */
/๋์๋ชฉ๋ก/๋์/์ ๋ชฉ
/* ์๋ ๊ฒฝ๋ก (ํ์ฌ ์ปจํ
์คํธ ๊ธฐ์ค) */
๋์/์ ๋ชฉ
/* ์ด๋์๋ ์ฐพ๊ธฐ (ํ์ ์ ์ฒด ํ์) */
//์ ๋ชฉ
/* ํน์ ์์ฑ์ผ๋ก ํํฐ๋ง */
//๋์[@id='001']
/* ์นดํ
๊ณ ๋ฆฌ๊ฐ 'ํ๋ก๊ทธ๋๋ฐ'์ธ ๋์์ ์ ๋ชฉ */
//๋์[@์นดํ
๊ณ ๋ฆฌ='ํ๋ก๊ทธ๋๋ฐ']/์ ๋ชฉ
/* ์ฒซ ๋ฒ์งธ ๋์ */
/๋์๋ชฉ๋ก/๋์[1]
/* ๋ง์ง๋ง ๋์ */
/๋์๋ชฉ๋ก/๋์[last()]
/* ๊ฐ๊ฒฉ์ด 30000 ์ด์์ธ ๋์ */
//๋์[๊ฐ๊ฒฉ >= 30000]
XPath์ ์ง์ง ๊ฐ๋ ฅํจ์ ์ถ(Axis)์ ์์ด.
ํ์ฌ ๋
ธ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ์ด๋ ๋ฐฉํฅ์ผ๋ก ํ์ํ ์ง ์ง์ ํ ์ ์๊ฑฐ๋ !
| ์ถ ์ด๋ฆ | ์๋ฏธ | ์์ |
|---|---|---|
| child:: | ์์ ๋ ธ๋ | child::๋์ |
| parent:: | ๋ถ๋ชจ ๋ ธ๋ | parent::๋์๋ชฉ๋ก |
| ancestor:: | ๋ชจ๋ ์กฐ์ ๋ ธ๋ | ancestor::๋์๋ชฉ๋ก |
| descendant:: | ๋ชจ๋ ์์ ๋ ธ๋ | descendant::์ ๋ชฉ |
| following-sibling:: | ๋ค์ ํ์ ๋ ธ๋๋ค | following-sibling::๋์ |
| preceding-sibling:: | ์ด์ ํ์ ๋ ธ๋๋ค | preceding-sibling::๋์ |
| attribute:: | ์์ฑ ๋ ธ๋ | attribute::id |
| self:: | ํ์ฌ ๋ ธ๋ ์์ | self::๋์ |
XPath๋ ๋จ์ ํ์์ ๋์ด ๋ค์ํ ๋ด์ฅ ํจ์๋ฅผ ์ ๊ณตํด. ์์ฃผ ์ฐ๋ ๊ฒ๋ค๋ง ์ ๋ฆฌํด๋ณผ๊ฒ!
/* ๋ฌธ์์ด ํจ์ */
string(๋
ธ๋) /* ๋
ธ๋๋ฅผ ๋ฌธ์์ด๋ก ๋ณํ */
concat('Hello', ' ', 'World') /* ๋ฌธ์์ด ์ฐ๊ฒฐ */
substring('ํ๋ก๊ทธ๋๋ฐ', 1, 3) /* ๋ถ๋ถ ๋ฌธ์์ด */
contains(์ ๋ชฉ, 'XML') /* ํฌํจ ์ฌ๋ถ ํ์ธ */
starts-with(์ ๋ชฉ, 'XML') /* ์์ ๋ฌธ์์ด ํ์ธ */
string-length(์ ๋ชฉ) /* ๋ฌธ์์ด ๊ธธ์ด */
normalize-space(์ ๋ชฉ) /* ์๋ค ๊ณต๋ฐฑ ์ ๊ฑฐ */
translate(์ ๋ชฉ, 'abc', 'ABC') /* ๋ฌธ์ ์นํ */
/* ์ซ์ ํจ์ */
count(//๋์) /* ๋
ธ๋ ๊ฐ์ */
sum(//๊ฐ๊ฒฉ) /* ํฉ๊ณ */
round(3.7) /* ๋ฐ์ฌ๋ฆผ โ 4 */
floor(3.7) /* ๋ด๋ฆผ โ 3 */
ceiling(3.2) /* ์ฌ๋ฆผ โ 4 */
/* ๋ถ๋ฆฌ์ธ ํจ์ */
not(@id) /* ์์ฑ์ด ์๋ ๊ฒฝ์ฐ */
true() /* ํญ์ ์ฐธ */
false() /* ํญ์ ๊ฑฐ์ง */
/* ๋
ธ๋ ์งํฉ ํจ์ */
position() /* ํ์ฌ ์์น ๋ฒํธ */
last() /* ๋ง์ง๋ง ์์น ๋ฒํธ */
name() /* ๋
ธ๋ ์ด๋ฆ */
local-name() /* ๋ค์์คํ์ด์ค ์ ์ธ ์ด๋ฆ */
XPath 1.0์ XSLT 1.0๊ณผ ํจ๊ป ์ฐ์ด๋ ๊ธฐ๋ณธ ๋ฒ์ ์ด๊ณ ,
XPath 2.0์ XSLT 2.0์์ ์ง์ํ๋ฉฐ ์ ๊ทํํ์, ์ํ์ค, ๊ฐ๋ ฅํ ํ์ ์์คํ ์ด ์ถ๊ฐ๋์ด.
ํ์ ์์๋ ์์ง 1.0๋ ๋ง์ด ์ฐ์ด๋ ๋ ๋ค ์์๋๋ฉด ์ข์!
์, ์ด์ ์ง์ง ๊ฝ์ธ XSLT(eXtensible Stylesheet Language Transformations)๋ฅผ ์์๋ณผ ์ฐจ๋ก์ผ! ๐ฉโจ
XSLT๋ XML ๋ฌธ์๋ฅผ ๋ค๋ฅธ ํ์์ผ๋ก ๋ณํํ๋ ์ธ์ด์ธ๋ฐ, ์ฌ๋ฐ๋ ๊ฑด XSLT ์์ฒด๋ XML ๋ฌธ์๋ผ๋ ๊ฑฐ์ผ.
์ฆ, XML๋ก XML์ ๋ณํํ๋ ๊ท์น์ ์์ฑํ๋ ์
์ด์ง. ๋ฉํ์ ์ด์ง ์์? ๐
XSLT ํ๋ก์ธ์(Saxon, Xalan, libxslt ๋ฑ)๊ฐ XML ์์ค ๋ฌธ์์ XSLT ์คํ์ผ์ํธ๋ฅผ ๋ฐ์์
HTML, ํ
์คํธ, ๋ค๋ฅธ XML, PDF(FO๋ฅผ ํตํด) ๋ฑ ๋ค์ํ ๊ฒฐ๊ณผ๋ฌผ์ ๋ง๋ค์ด๋ด.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- ์ถ๋ ฅ ํ์ ์ง์ -->
<xsl:output method="html" encoding="UTF-8" indent="yes"/>
<!-- ๋ฃจํธ ํ
ํ๋ฆฟ -->
<xsl:template match="/">
<html>
<body>
<h1>๋์ ๋ชฉ๋ก</h1>
<xsl:apply-templates select="๋์๋ชฉ๋ก/๋์"/>
</body>
</html>
</xsl:template>
<!-- ๋์ ์์ ์ฒ๋ฆฌ ํ
ํ๋ฆฟ -->
<xsl:template match="๋์">
<div>
<h2><xsl:value-of select="์ ๋ชฉ"/></h2>
<p>์ ์: <xsl:value-of select="์ ์"/></p>
<p>๊ฐ๊ฒฉ: <xsl:value-of select="๊ฐ๊ฒฉ"/>์</p>
</div>
</xsl:template>
</xsl:stylesheet>
match ์์ฑ์ XPath๋ฅผ ์จ์ ์ด๋ค ๋
ธ๋์ ์ ์ฉํ ์ง ์ง์ ํด.name ์์ฑ์ผ๋ก ์ด๋ฆ์ ๋ถ์ด๋ฉด xsl:call-template๋ก ํธ์ถ ๊ฐ๋ฅํ ํจ์์ฒ๋ผ ์ธ ์ ์์ด.
<!-- match๋ก ํจํด ๋งค์นญ -->
<xsl:template match="๋์[@์นดํ
๊ณ ๋ฆฌ='ํ๋ก๊ทธ๋๋ฐ']">
<span style="color:blue">
<xsl:value-of select="์ ๋ชฉ"/>
</span>
</xsl:template>
<!-- name์ผ๋ก ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ํ
ํ๋ฆฟ -->
<xsl:template name="๊ฐ๊ฒฉํฌ๋งท">
<xsl:param name="๊ธ์ก"/>
<xsl:value-of select="format-number($๊ธ์ก, '#,###')"/>์
</xsl:template>
์ ํ๋ ๋ ธ๋ ์งํฉ์ ์ํํ๋ฉด์ ๋์ผํ ์ฒ๋ฆฌ๋ฅผ ๋ฐ๋ณตํด. ํ๋ก๊ทธ๋๋ฐ์ for ๋ฃจํ์ ๋น์ทํด!
<xsl:for-each select="๋์๋ชฉ๋ก/๋์">
<!-- ์ ๋ ฌ๋ ๊ฐ๋ฅ! -->
<xsl:sort select="๊ฐ๊ฒฉ" data-type="number" order="ascending"/>
<tr>
<td><xsl:value-of select="position()"/></td>
<td><xsl:value-of select="์ ๋ชฉ"/></td>
<td><xsl:value-of select="๊ฐ๊ฒฉ"/></td>
</tr>
</xsl:for-each>
ํ๋ก๊ทธ๋๋ฐ์ if-else, switch-case์ ๊ฐ์ ์ญํ ์ด์ผ!
<!-- ๋จ์ ์กฐ๊ฑด -->
<xsl:if test="๊ฐ๊ฒฉ > 30000">
<span class="expensive">๊ณ ๊ฐ ๋์</span>
</xsl:if>
<!-- ๋ค์ค ์กฐ๊ฑด (if-else if-else) -->
<xsl:choose>
<xsl:when test="๊ฐ๊ฒฉ < 20000">
<span style="color:green">์ ๋ ด</span>
</xsl:when>
<xsl:when test="๊ฐ๊ฒฉ < 35000">
<span style="color:orange">๋ณดํต</span>
</xsl:when>
<xsl:otherwise>
<span style="color:red">๊ณ ๊ฐ</span>
</xsl:otherwise>
</xsl:choose>
XSLT์์ ๋ณ์๋ ํ ๋ฒ ์ค์ ํ๋ฉด ๋ณ๊ฒฝ ๋ถ๊ฐ(๋ถ๋ณ)์ผ. ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๋๋!
<!-- ๋ณ์ ์ ์ธ -->
<xsl:variable name="์ด๋์์" select="count(//๋์)"/>
<xsl:variable name="ํ๊ท ๊ฐ๊ฒฉ" select="sum(//๊ฐ๊ฒฉ) div $์ด๋์์"/>
<p>์ด <xsl:value-of select="$์ด๋์์"/>๊ถ,
ํ๊ท ๊ฐ๊ฒฉ: <xsl:value-of select="format-number($ํ๊ท ๊ฐ๊ฒฉ, '#,###')"/>์
</p>
<!-- ํ๋ผ๋ฏธํฐ (์ธ๋ถ์์ ๊ฐ ์ ๋ฌ ๊ฐ๋ฅ) -->
<xsl:param name="์ ํ์นดํ
๊ณ ๋ฆฌ" select="'์ ์ฒด'"/>
์ด ๋์ ์ฐจ์ด๋ฅผ ํท๊ฐ๋ คํ๋ ์ฌ๋์ด ๋ง์๋ฐ, ๋ช ํํ๊ฒ ์ ๋ฆฌํด์ค๊ฒ!
| ๊ตฌ๋ถ | xsl:apply-templates | xsl:call-template |
|---|---|---|
| ๋์ ๋ฐฉ์ | ํจํด ๋งค์นญ์ผ๋ก ์๋ ์ ํ | ์ด๋ฆ์ผ๋ก ์ง์ ํธ์ถ |
| ์ปจํ ์คํธ ๋ณ๊ฒฝ | ์ ํ๋ ๋ ธ๋๋ก ๋ณ๊ฒฝ๋จ | ํ์ฌ ์ปจํ ์คํธ ์ ์ง |
| ๋น์ | ๋คํ์ฑ(Polymorphism) | ํจ์ ํธ์ถ |
| ์ฌ์ฉ ์์ | ๋ ธ๋ ํ์ ๋ณ ๋ค๋ฅธ ์ฒ๋ฆฌ | ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๋ก์ง |
์ด์ ์ด๋ก ์ ์ถฉ๋ถํ ๋ดค์ผ๋, ์ค์ ๋ก ๋์ํ๋ ์์ ๋ฅผ ์ฒ์๋ถํฐ ๋๊น์ง ๋ง๋ค์ด๋ณด์!
๋์ ๋ชฉ๋ก XML์ ์์ HTML ํ
์ด๋ธ๋ก ๋ณํํ๋ ์์ ํ ์์ ์ผ. ๐ช
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="books.xsl"?>
<๋์๋ชฉ๋ก>
<๋์ id="001" ์นดํ
๊ณ ๋ฆฌ="ํ๋ก๊ทธ๋๋ฐ" ์ถ์ฒ="true">
<์ ๋ชฉ>XML ๋ง์คํฐํ๊ธฐ</์ ๋ชฉ>
<์ ์>ํ๊ธธ๋</์ ์>
<์ถํ์ฌ>ํ
ํฌ๋ถ์ค</์ถํ์ฌ>
<์ถํ๋
๋>2024</์ถํ๋
๋>
<๊ฐ๊ฒฉ>28000</๊ฐ๊ฒฉ>
<์ฌ๊ณ >15</์ฌ๊ณ >
</๋์>
<๋์ id="002" ์นดํ
๊ณ ๋ฆฌ="์น๊ฐ๋ฐ">
<์ ๋ชฉ>XSLT ์ค์ ๊ฐ์ด๋</์ ๋ชฉ>
<์ ์>๊น์ฒ ์</์ ์>
<์ถํ์ฌ>์ฝ๋ฉํ์ฐ์ค</์ถํ์ฌ>
<์ถํ๋
๋>2023</์ถํ๋
๋>
<๊ฐ๊ฒฉ>32000</๊ฐ๊ฒฉ>
<์ฌ๊ณ >0</์ฌ๊ณ >
</๋์>
<๋์ id="003" ์นดํ
๊ณ ๋ฆฌ="ํ๋ก๊ทธ๋๋ฐ" ์ถ์ฒ="true">
<์ ๋ชฉ>XPath ์๋ฒฝ ๋ ์ํผ</์ ๋ชฉ>
<์ ์>์ด์ํฌ</์ ์>
<์ถํ์ฌ>๋ฐ์ดํฐ๋ถ</์ถํ์ฌ>
<์ถํ๋
๋>2024</์ถํ๋
๋>
<๊ฐ๊ฒฉ>25000</๊ฐ๊ฒฉ>
<์ฌ๊ณ >8</์ฌ๊ณ >
</๋์>
</๋์๋ชฉ๋ก>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8" indent="yes"
doctype-public="-//W3C//DTD HTML 4.01//EN"/>
<!-- ์ ์ญ ๋ณ์ -->
<xsl:variable name="์ด๋์์" select="count(//๋์)"/>
<xsl:variable name="์ด์ฌ๊ณ " select="sum(//์ฌ๊ณ )"/>
<xsl:variable name="ํ๊ท ๊ฐ๊ฒฉ"
select="sum(//๊ฐ๊ฒฉ) div $์ด๋์์"/>
<!-- ๋ฃจํธ ํ
ํ๋ฆฟ -->
<xsl:template match="/">
<html>
<head>
<title>๋์ ๋ชฉ๋ก</title>
<style>
table { border-collapse: collapse; width: 100%; }
th { background: #7ab3cc; color: white; padding: 10px; }
td { padding: 8px; border-bottom: 1px solid #ddd; }
.์ถ์ฒ { background: #fffde7; }
.ํ์ { color: red; font-weight: bold; }
.ํต๊ณ { background: #f4f9fc; padding: 12px; margin-bottom: 16px; }
</style>
</head>
<body>
<h1>๐ ๋์ ๋ชฉ๋ก</h1>
<!-- ํต๊ณ ์น์
-->
<div class="ํต๊ณ">
<strong>์ด ๋์ ์:</strong>
<xsl:value-of select="$์ด๋์์"/>๊ถ |
<strong>์ด ์ฌ๊ณ :</strong>
<xsl:value-of select="$์ด์ฌ๊ณ "/>๊ถ |
<strong>ํ๊ท ๊ฐ๊ฒฉ:</strong>
<xsl:value-of select="format-number($ํ๊ท ๊ฐ๊ฒฉ,'#,###')"/>์
</div>
<table>
<tr>
<th>๋ฒํธ</th>
<th>์ ๋ชฉ</th>
<th>์ ์</th>
<th>์นดํ
๊ณ ๋ฆฌ</th>
<th>๊ฐ๊ฒฉ</th>
<th>์ฌ๊ณ </th>
</tr>
<!-- ๊ฐ๊ฒฉ ์ค๋ฆ์ฐจ์ ์ ๋ ฌ -->
<xsl:apply-templates select="๋์๋ชฉ๋ก/๋์">
<xsl:sort select="๊ฐ๊ฒฉ" data-type="number"/>
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<!-- ๋์ ํ ํ
ํ๋ฆฟ -->
<xsl:template match="๋์">
<tr>
<!-- ์ถ์ฒ ๋์๋ ๋ฐฐ๊ฒฝ์ ๋ค๋ฅด๊ฒ -->
<xsl:if test="@์ถ์ฒ='true'">
<xsl:attribute name="class">์ถ์ฒ</xsl:attribute>
</xsl:if>
<td><xsl:value-of select="position()"/></td>
<td>
<xsl:value-of select="์ ๋ชฉ"/>
<xsl:if test="@์ถ์ฒ='true'"> โญ</xsl:if>
</td>
<td><xsl:value-of select="์ ์"/></td>
<td><xsl:value-of select="@์นดํ
๊ณ ๋ฆฌ"/></td>
<td>
<xsl:value-of select="format-number(๊ฐ๊ฒฉ,'#,###')"/>์
</td>
<td>
<xsl:choose>
<xsl:when test="์ฌ๊ณ = 0">
<span class="ํ์ ">ํ์ </span>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="์ฌ๊ณ "/>๊ถ
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
XML ํ์ผ์
<?xml-stylesheet type="text/xsl" href="books.xsl"?>๋ฅผ ์ถ๊ฐํ๋ฉด๋ธ๋ผ์ฐ์ (Chrome, Firefox)์์ XML ํ์ผ์ ์ด์์ ๋ ์๋์ผ๋ก XSLT ๋ณํ์ด ์ ์ฉ๋ผ!
๋จ, Chrome์ ๋ก์ปฌ ํ์ผ ๋ณด์ ์ ์ฑ ์ผ๋ก ์๋ฒ ํ๊ฒฝ์ด ํ์ํ ์ ์์ด.
์ค์ ๊ฐ๋ฐ์์๋ ๋ธ๋ผ์ฐ์ ๋ ๋๋ง๋ณด๋ค ์๋ฒ ์ฌ์ด๋์์ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ๊ฐ ํจ์ฌ ๋ง์.
์ฃผ์ ์ธ์ด๋ณ๋ก ์ด๋ป๊ฒ XML๊ณผ XSLT๋ฅผ ๋ค๋ฃจ๋์ง ์์๋ณด์! ๐ฅ๏ธ
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
public class XSLTProcessor {
public static void main(String[] args) throws Exception {
// TransformerFactory ์์ฑ
TransformerFactory factory = TransformerFactory.newInstance();
// XSLT ์คํ์ผ์ํธ ๋ก๋
Source xslt = new StreamSource(new File("books.xsl"));
Transformer transformer = factory.newTransformer(xslt);
// ํ๋ผ๋ฏธํฐ ์ ๋ฌ (์ ํ์ฌํญ)
transformer.setParameter("์ ํ์นดํ
๊ณ ๋ฆฌ", "ํ๋ก๊ทธ๋๋ฐ");
// ๋ณํ ์คํ
Source xml = new StreamSource(new File("books.xml"));
Result output = new StreamResult(new File("output.html"));
transformer.transform(xml, output);
System.out.println("๋ณํ ์๋ฃ!");
}
}
from lxml import etree
# XML ํ์ฑ
xml_doc = etree.parse('books.xml')
# XSLT ์คํ์ผ์ํธ ๋ก๋
xslt_doc = etree.parse('books.xsl')
transform = etree.XSLT(xslt_doc)
# ํ๋ผ๋ฏธํฐ ์ ๋ฌ (๋ฌธ์์ด์ ๋ฐ์ดํ ํฌํจ!)
params = {
'์ ํ์นดํ
๊ณ ๋ฆฌ': etree.XSLT.strparam('ํ๋ก๊ทธ๋๋ฐ')
}
# ๋ณํ ์คํ
result = transform(xml_doc, **params)
# ๊ฒฐ๊ณผ ์ ์ฅ
with open('output.html', 'wb') as f:
f.write(bytes(result))
# XPath๋ก ๋
ธ๋ ์ ํ
root = xml_doc.getroot()
titles = root.xpath('//์ ๋ชฉ/text()')
print(titles) # ['XML ๋ง์คํฐํ๊ธฐ', 'XSLT ์ค์ ๊ฐ์ด๋', ...]
# ์กฐ๊ฑด๋ถ XPath
expensive = root.xpath('//๋์[๊ฐ๊ฒฉ > 30000]/์ ๋ชฉ/text()')
print(expensive)
const xslt4node = require('xslt4node');
const fs = require('fs');
// ์ค์ ๊ฐ์ฒด
const config = {
xsltPath: 'books.xsl',
sourcePath: 'books.xml',
result: 'output.html',
params: {
'์ ํ์นดํ
๊ณ ๋ฆฌ': 'string:ํ๋ก๊ทธ๋๋ฐ'
}
};
// ๋ณํ ์คํ
xslt4node.transform(config, (err) => {
if (err) {
console.error('๋ณํ ์ค๋ฅ:', err);
} else {
console.log('๋ณํ ์ฑ๊ณต!');
}
});
// ๋ธ๋ผ์ฐ์ ์์๋ DOMParser + XSLTProcessor ์ฌ์ฉ
const parser = new DOMParser();
const xsltProcessor = new XSLTProcessor();
fetch('books.xsl')
.then(r => r.text())
.then(xsltText => {
const xsltDoc = parser.parseFromString(xsltText, 'text/xml');
xsltProcessor.importStylesheet(xsltDoc);
return fetch('books.xml');
})
.then(r => r.text())
.then(xmlText => {
const xmlDoc = parser.parseFromString(xmlText, 'text/xml');
const resultDoc = xsltProcessor.transformToDocument(xmlDoc);
document.body.appendChild(resultDoc.documentElement);
});
using System.Xml;
using System.Xml.Xsl;
class Program {
static void Main() {
// XslCompiledTransform ์ฌ์ฉ (์ฑ๋ฅ ์ต์ ํ)
var xslt = new XslCompiledTransform();
xslt.Load("books.xsl");
// ํ๋ผ๋ฏธํฐ ์ค์
var args = new XsltArgumentList();
args.AddParam("์ ํ์นดํ
๊ณ ๋ฆฌ", "", "ํ๋ก๊ทธ๋๋ฐ");
// ๋ณํ ์คํ
using var writer = new XmlTextWriter("output.html",
System.Text.Encoding.UTF8);
xslt.Transform("books.xml", args, writer);
Console.WriteLine("๋ณํ ์๋ฃ!");
}
}
๊ธฐ๋ณธ๊ธฐ๋ฅผ ๋ค์ก์ผ๋ฉด ์ด์ ์ข ๋ ๊ณ ๊ธ ๊ธฐ๋ฒ๋ค์ ์ดํด๋ณด์.
์ด๊ฑธ ์๋ฉด ์ง์ง XSLT ๊ณ ์ ์๋ฆฌ ๋ค์ ์ ์์ด! ๐
XSLT์๋ ๋ฃจํ๊ฐ ์์ด์ ๋ณต์กํ ๋ฐ๋ณต ์ฒ๋ฆฌ๋ ์ฌ๊ท ํ
ํ๋ฆฟ์ผ๋ก ๊ตฌํํด์ผ ํด.
์ฒ์์ ์ด์ํ์ง๋ง ์ต์ํด์ง๋ฉด ๊ฐ๋ ฅํ ๋๊ตฌ๊ฐ ๋ผ!
<!-- ์ซ์๋ฅผ N๋ฒ ๋ฐ๋ณต ์ถ๋ ฅํ๋ ์ฌ๊ท ํ
ํ๋ฆฟ -->
<xsl:template name="๋ฐ๋ณต์ถ๋ ฅ">
<xsl:param name="ํ์" select="0"/>
<xsl:param name="ํ์ฌ" select="1"/>
<xsl:param name="ํ
์คํธ"/>
<xsl:if test="$ํ์ฌ <= $ํ์">
<xsl:value-of select="$ํ
์คํธ"/>
<!-- ์ฌ๊ท ํธ์ถ -->
<xsl:call-template name="๋ฐ๋ณต์ถ๋ ฅ">
<xsl:with-param name="ํ์" select="$ํ์"/>
<xsl:with-param name="ํ์ฌ" select="$ํ์ฌ + 1"/>
<xsl:with-param name="ํ
์คํธ" select="$ํ
์คํธ"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- ํธ์ถ ์์: "โ
"์ 5๋ฒ ์ถ๋ ฅ -->
<xsl:call-template name="๋ฐ๋ณต์ถ๋ ฅ">
<xsl:with-param name="ํ์" select="5"/>
<xsl:with-param name="ํ
์คํธ">โ
</xsl:with-param>
</xsl:call-template>
์ค๋ฌด์์ XML์ ๋ค๋ฃจ๋ค ๋ณด๋ฉด ๋ค์์คํ์ด์ค ๋๋ฌธ์ ๊ณจ์น ์ํ ๊ฒฝ์ฐ๊ฐ ๋ง์.
ํนํ SOAP ์น์๋น์ค๋ Office XML ํ์ผ ์ฒ๋ฆฌํ ๋ ์์ฃผ ๋ง๋๊ฒ ๋ผ.
<!-- ๋ค์์คํ์ด์ค๊ฐ ์๋ XML -->
<root xmlns:์ฑ
="http://example.com/book"
xmlns:์ ์="http://example.com/author">
<์ฑ
:๋์>
<์ฑ
:์ ๋ชฉ>XML ๋ง์คํฐํ๊ธฐ</์ฑ
:์ ๋ชฉ>
<์ ์:์ด๋ฆ>ํ๊ธธ๋</์ ์:์ด๋ฆ>
</์ฑ
:๋์>
</root>
<!-- XSLT์์ ๋ค์์คํ์ด์ค ์ ์ธ ํ ์ฌ์ฉ -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:์ฑ
="http://example.com/book"
xmlns:์ ์="http://example.com/author">
<xsl:template match="/">
<!-- ๋ค์์คํ์ด์ค ์ ๋์ฌ๋ก ์์ ์ ํ -->
<xsl:value-of select="//์ฑ
:์ ๋ชฉ"/>
<xsl:value-of select="//์ ์:์ด๋ฆ"/>
</xsl:template>
</xsl:stylesheet>
XSLT 1.0์์ SQL์ GROUP BY ๊ฐ์ ๊ทธ๋ฃนํ์ ๊ตฌํํ๋ ๊ณ ์ ์ ์ธ ๊ธฐ๋ฒ์ด์ผ.
xsl:key๋ฅผ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ธ๋ฐ, ์์๋๋ฉด ์ ๋ง ์ ์ฉํด!
<!-- ์นดํ
๊ณ ๋ฆฌ๋ณ ๊ทธ๋ฃนํ (Muenchian ๋ฐฉ๋ฒ) -->
<!-- 1๋จ๊ณ: key ์ ์ -->
<xsl:key name="์นดํ
๊ณ ๋ฆฌ๋ณ" match="๋์" use="@์นดํ
๊ณ ๋ฆฌ"/>
<!-- 2๋จ๊ณ: ๊ณ ์ ์นดํ
๊ณ ๋ฆฌ๋ง ์ ํ -->
<xsl:template match="/">
<xsl:for-each select="//๋์[
generate-id() = generate-id(
key('์นดํ
๊ณ ๋ฆฌ๋ณ', @์นดํ
๊ณ ๋ฆฌ)[1]
)
]">
<h2>๐ <xsl:value-of select="@์นดํ
๊ณ ๋ฆฌ"/></h2>
<!-- 3๋จ๊ณ: ํด๋น ์นดํ
๊ณ ๋ฆฌ์ ๋ชจ๋ ๋์ ์ถ๋ ฅ -->
<xsl:for-each select="key('์นดํ
๊ณ ๋ฆฌ๋ณ', @์นดํ
๊ณ ๋ฆฌ)">
<p>- <xsl:value-of select="์ ๋ชฉ"/></p>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
XSLT 1.0์ ๊ฐ๋ ฅํ์ง๋ง ๋ช ๊ฐ์ง ํ๊ณ๊ฐ ์์ด:
- ๋ณ์ ๊ฐ ๋ณ๊ฒฝ ๋ถ๊ฐ (ํจ์ํ ํน์ฑ)
- ์ ๊ทํํ์ ๋ฏธ์ง์
- ๋ ์ง/์๊ฐ ์ฒ๋ฆฌ ํจ์ ์์
- ๋ณต์กํ ๋ฌธ์์ด ์ฒ๋ฆฌ ์ด๋ ค์
์ด๋ฐ ๊ฒฝ์ฐ์ XSLT 2.0/3.0์ด๋ extension ํจ์๋ฅผ ํ์ฉํด์ผ ํด!
XML์ ์ ๋๋ก ๋ค๋ฃจ๋ ค๋ฉด XML Schema Definition(XSD)๋ ์์์ผ ํด.
XSD๋ XML ๋ฌธ์์ ๊ตฌ์กฐ, ๋ฐ์ดํฐ ํ์
, ์ ์ฝ ์กฐ๊ฑด์ ์ ์ํ๋ ์ธ์ด์ผ.
๋ง์น ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์คํค๋ง์ฒ๋ผ, XML ๋ฌธ์๊ฐ ์ฌ๋ฐ๋ฅธ ํ์์ธ์ง ๊ฒ์ฆํ ์ ์์ด. ๐
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- ๋์๋ชฉ๋ก ๋ฃจํธ ์์ ์ ์ -->
<xs:element name="๋์๋ชฉ๋ก">
<xs:complexType>
<xs:sequence>
<xs:element name="๋์" type="๋์ํ์
"
minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- ๋์ ํ์
์ ์ -->
<xs:complexType name="๋์ํ์
">
<xs:sequence>
<xs:element name="์ ๋ชฉ" type="xs:string"/>
<xs:element name="์ ์" type="xs:string"/>
<xs:element name="์ถํ๋
๋">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="1900"/>
<xs:maxInclusive value="2099"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="๊ฐ๊ฒฉ" type="xs:positiveInteger"/>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="์นดํ
๊ณ ๋ฆฌ" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="ํ๋ก๊ทธ๋๋ฐ"/>
<xs:enumeration value="์น๊ฐ๋ฐ"/>
<xs:enumeration value="๋ฐ์ดํฐ๋ฒ ์ด์ค"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>
"์์ฆ JSON์ด ๋์ธ์ธ๋ฐ XML์ด ์์ง๋ ์ฐ์ฌ?" ๋ผ๊ณ ์๊ฐํ ์ ์๋๋ฐ,
์ค์ ๋ก XML์ ์์ฒญ๋๊ฒ ๋ง์ ๊ณณ์์ ์ฌ์ ํ ํต์ฌ ๊ธฐ์ ๋ก ํ์ฉ๋๊ณ ์์ด! ๐ญ
์ ์์ธ๊ธ๊ณ์ฐ์, ๊ธ์ต EDI, ๊ณต๊ณต ๋ฐ์ดํฐ API, ์ ์์ ๋ถ ํ์คํ๋ ์์ํฌ
DocBook, DITA, XSL-FO๋ก PDF ์์ฑ, ์ ์์ฑ (EPUB) ์ ์
SOAP ์น์๋น์ค, SAP/Oracle ERP ์ฐ๋, ESB ๋ฉ์์ง ๋ณํ
Android ๋ ์ด์์, iOS plist, ์ฑ ์ค์ ํ์ผ, ๋ฆฌ์์ค ๊ด๋ฆฌ
SVG, MathML, RSS/Atom ํผ๋, XHTML, WSDL
Maven/Ant ๋น๋ ์ค์ , Spring ์ค์ , JUnit ๋ฆฌํฌํธ
์ฌ๋ฅ๋ท์์๋ XML ๋ฐ์ดํฐ ์ฒ๋ฆฌ, XSLT ๋ณํ ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ, XML Schema ์ค๊ณ ๊ฐ์
์ ๋ฌธ์ ์ธ XML ๊ด๋ จ ๊ฐ๋ฐ ์ฌ๋ฅ์ ๊ฑฐ๋ํ ์ ์์ด. ํ๋ฆฌ๋์ ๊ฐ๋ฐ์๋ผ๋ฉด ์ด๋ฐ ํ์ ๊ธฐ์ ์ด
๊ฒฝ์๋ ฅ์ด ๋ ์ ์๋ค๋ ๊ฑฐ ์์๋ฌ! ๐
XSLT ๊ฐ๋ฐํ๋ค ๋ณด๋ฉด "์ ์ ๋์ง?" ํ๋ ์๊ฐ์ด ๋ฐ๋์ ์. ๐
๊ทธ๋ด ๋ ๋์์ด ๋๋ ๋๊ตฌ๋ค์ ์๊ฐํ ๊ฒ!
| ๋๊ตฌ | ์ข ๋ฅ | ํน์ง |
|---|---|---|
| Saxon HE/PE/EE | XSLT ํ๋ก์ธ์ | XSLT 2.0/3.0 ์ง์, ๊ฐ์ฅ ๊ฐ๋ ฅํ ์คํ์์ค ํ๋ก์ธ์ |
| Oxygen XML Editor | IDE | XML/XSLT ์ ์ฉ IDE, ๋๋ฒ๊ฑฐ ๋ด์ฅ, ์ ๋ฃ |
| Altova XMLSpy | IDE | ์ํฐํ๋ผ์ด์ฆ๊ธ XML ๊ฐ๋ฐ ํ๊ฒฝ, ์ ๋ฃ |
| VS Code + XML ํ์ฅ | ์๋ํฐ | ๋ฌด๋ฃ, Red Hat XML ํ์ฅ์ผ๋ก ์คํค๋ง ๊ฒ์ฆ ๊ฐ๋ฅ |
| xsltproc | CLI ๋๊ตฌ | ๋ฆฌ๋ ์ค ๊ธฐ๋ณธ ํ์ฌ, libxslt ๊ธฐ๋ฐ, ๋น ๋ฅธ ์ฒ๋ฆฌ |
| Online XSLT Tester | ์น ๋๊ตฌ | xsltransform.net ๋ฑ, ๋น ๋ฅธ ํ ์คํธ์ฉ |
xsl:template match์ XPath๊ฐ ์๋ชป๋์ ๋ ๋ฐ์.โ
xsl:message๋ก ์ค๊ฐ ๊ฐ ์ถ๋ ฅํด์ ๋๋ฒ๊น
ํ๊ฑฐ๋, XPath๋ฅผ ๋จ๊ณ์ ์ผ๋ก ํ
์คํธํด๋ด.
์์ค XML์ ๋ค์์คํ์ด์ค๊ฐ ์๋๋ฐ XSLT์์ ์ ์ธ ์ ํ์ ๋.
โ XSLT ๋ฃจํธ ์์์ ๋์ผํ ๋ค์์คํ์ด์ค URI๋ฅผ ์ ์ธํด์ผ ํด.
xsl:apply-templates๊ฐ ์๊ธฐ ์์ ์ ๊ณ์ ํธ์ถํ ๋.โ
select ์์ฑ์ผ๋ก ์ฒ๋ฆฌํ ๋
ธ๋๋ฅผ ๋ช
ํํ ์ง์ ํด์ผ ํด.
<!-- ๋๋ฒ๊น
์ฉ xsl:message ํ์ฉ -->
<xsl:template match="๋์">
<!-- ์ฝ์์ ๋ฉ์์ง ์ถ๋ ฅ (terminate="yes"๋ฉด ์ฒ๋ฆฌ ์ค๋จ) -->
<xsl:message>
ํ์ฌ ์ฒ๋ฆฌ ์ค์ธ ๋์: <xsl:value-of select="์ ๋ชฉ"/>
๊ฐ๊ฒฉ: <xsl:value-of select="๊ฐ๊ฒฉ"/>
</xsl:message>
<!-- ์ค์ ์ฒ๋ฆฌ ๋ด์ฉ -->
</xsl:template>
2017๋
์ W3C ํ์ค์ด ๋ XSLT 3.0์ ๊ธฐ์กด์ ํ๊ณ๋ฅผ ๋ง์ด ๊ทน๋ณตํ์ด.
Saxon 9.8+ ๋ฒ์ ์์ ์์ ์ง์ํ๊ณ , ํ๋์ ์ธ ๊ฐ๋ฐ ํจํด์ ๋ง์ด ๋์
ํ์ง. ๐
์ GB์ง๋ฆฌ XML๋ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌ ๊ฐ๋ฅ
JSON๊ณผ ์ ์ฌํ ๋งต/๋ฐฐ์ด ๋ฐ์ดํฐ ํ์ ์ง์
json-to-xml(), xml-to-json() ํจ์๋ก JSON ๋ณํ
<!-- XSLT 3.0: JSON์ XML๋ก ๋ณํ ํ ์ฒ๋ฆฌ -->
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="xsl:initial-template">
<!-- JSON ๋ฌธ์์ด์ XML๋ก ๋ณํ -->
<xsl:variable name="json-text">
{"๋์": [{"์ ๋ชฉ": "XML ๋ง์คํฐํ๊ธฐ", "๊ฐ๊ฒฉ": 28000}]}
</xsl:variable>
<xsl:variable name="xml-data"
select="json-to-xml($json-text)"/>
<!-- ๋ณํ๋ XML ์ฒ๋ฆฌ -->
<xsl:for-each select="$xml-data//map[@key='๋์']/map">
<p><xsl:value-of select="string[@key='์ ๋ชฉ']"/></p>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
XML/XSLT/XPath๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๋ฐฐ์ฐ๊ณ ์ถ๋ค๋ฉด ์ด ์์๋ก ๊ณต๋ถํด๋ด!
๊ทธ๋ฆฌ๊ณ ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ ์ค์ ํ๋ก์ ํธ ๊ฒฝํ์ ์๋ ๊ฒ๋ ์ ๋ง ์ข์ ๋ฐฉ๋ฒ์ด์ผ. ๐
1๋จ๊ณ (1~2์ฃผ): XML ๊ธฐ๋ณธ ๋ฌธ๋ฒ, Well-formed/Valid ๊ฐ๋ , DTD ๊ธฐ์ด
2๋จ๊ณ (2~3์ฃผ): XPath 1.0 ์์ ์ ๋ณต - ์ถ, ํจ์, ์กฐ๊ฑด์
3๋จ๊ณ (3~4์ฃผ): XSLT 1.0 ํต์ฌ ์์ - template, for-each, if/choose
4๋จ๊ณ (2~3์ฃผ): XML Schema(XSD) ์ค๊ณ ๋ฐ ๊ฒ์ฆ
5๋จ๊ณ (์ง์): ์ค์ ํ๋ก์ ํธ - ์ค์ XML ๋ฐ์ดํฐ ๋ณํ ์์
6๋จ๊ณ (์ ํ): XSLT 2.0/3.0, XPath 2.0, Saxon ๊ณ ๊ธ ๊ธฐ๋ฅ
| ์๋ฃ | ํน์ง |
|---|---|
| W3Schools XML/XSLT ํํ ๋ฆฌ์ผ | ๋ฌด๋ฃ, ์ธํฐ๋ํฐ๋ธ ์์ , ์ ๋ฌธ์ ์ต์ |
| W3C ๊ณต์ ์คํ | ๊ฐ์ฅ ์ ํํ ๋ ํผ๋ฐ์ค, ์์ด |
| XSLT 2.0 and XPath 2.0 (Michael Kay) | Saxon ๊ฐ๋ฐ์๊ฐ ์ด ๋ฐ์ด๋ธ, ์ฌํ ํ์ต |
| XPath and XPointer (John Simpson) | XPath ์ ๋ฌธ์, O'Reilly |
| Stack Overflow xml ํ๊ทธ | ์ค๋ฌด ๋ฌธ์ ํด๊ฒฐ์ ๋ณด๊ณ |
๊ณต๊ณต๋ฐ์ดํฐํฌํธ(data.go.kr)์์ XML ํ์์ ๊ณต๊ณต API๋ฅผ ๋ฐ์์
XSLT๋ก HTML ๋ฆฌํฌํธ๋ฅผ ๋ง๋ค์ด๋ณด๋ ์ฐ์ต์ด ์ต๊ณ ์ผ.
์ค์ ๋ฐ์ดํฐ๋ก ์์ ํ๋ฉด ์ด๋ก ๋ง ๊ณต๋ถํ ๋์ ์ฐจ์์ด ๋ค๋ฅธ ์ดํด๊ฐ ์๊ฒจ! ๐ฏ
์, ์ฌ๊ธฐ๊น์ง XML, XPath, XSLT์ ์ธ๊ณ๋ฅผ ํจ๊ป ํํํด๋ดค์ด! ๐
์ฒ์์ ๋ณต์กํด ๋ณด์ด์ง๋ง, ์ด ์ธ ๊ธฐ์ ์ ์๋ก ์๋ฒฝํ๊ฒ ๋ง๋ฌผ๋ ค์ ๋์ํ๋ ๊ฐ๋ ฅํ ์ํ๊ณ์ผ.
XML์ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํ๊ณ ,
XPath๋ ๊ทธ ๊ตฌ์กฐ ์์์ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ ํํ ์ฐพ์๋ด๊ณ ,
XSLT๋ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์ํ๋ ํํ๋ก ๋ณํํด๋ด์ง.
JSON์ด ๋์ธ์ธ ์๋์๋ XML์ ์ฌ์ ํ ์ํฐํ๋ผ์ด์ฆ, ๊ณต๊ณต, ์ถํ, ํ์ค ๋ฌธ์ ๋ถ์ผ์์
์์ด์๋ ์ ๋ ํต์ฌ ๊ธฐ์ ์ด์ผ. ํนํ ๋ ๊ฑฐ์ ์์คํ
์ฐ๋์ด๋ ๋ณต์กํ ๋ฌธ์ ๋ณํ ์์
์์
XML/XSLT ๋ฅ๋ ฅ์๋ ์ ๋ง ๊ทํ ์กด์ฌ๊ฐ ๋ ์ ์์ด. ๐
XML = ๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ ํํ XPath = ๋ ธ๋ ํ์ ์ธ์ด XSLT = ๋ณํ ๊ท์น ์ธ์ด XSD = ์คํค๋ง ๊ฒ์ฆ Saxon = ์ต๊ฐ XSLT ํ๋ก์ธ์ lxml = Python XML ๋ผ์ด๋ธ๋ฌ๋ฆฌ JAXP = Java XML API
์ด ๊ธ์ ๋ค ์ฝ์ ๋๋ ์ด๋ฏธ XML ํธ๋ฆฌ์ค์ ๊ธฐ์ด๋ฅผ ์์ ํ ์ดํดํ ๊ฑฐ์ผ! ๐
์ด์ ์ง์ ์ฝ๋๋ฅผ ์์ฑํด๋ณด๊ณ , ์ค์ XML ๋ฐ์ดํฐ๋ฅผ ๋ณํํด๋ณด๋ฉด์ ์ค๋ ฅ์ ํค์๋ด.
๋งํ๋ ๋ถ๋ถ์ด ์์ผ๋ฉด W3C ์คํ๊ณผ Stack Overflow๊ฐ ํญ์ ๊ณ์ ์๋ค๋ ๊ฒ๋ ์์ง ๋ง! ๐
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.