XSLT를 통한 문서변환 with PHP

XML 문서는 데이터와 구조정보만 제공.

어떻게 보여질 것인지에 대해서 XSL (eXtengible Stylesheet Language) 이라는 스타일시트 제공



1. XSL의 구성 : XSL 스타일시트는 3가지로 구성됨.



- XSLT : XSL Transformations (문서구조 변환 기능)

- XPATH : XML Path Language (문서 변환 시 기존 문서에서 가져올 특정노드를 가리키는 기능)

- XSL-FO : XSL Formmatting Objects (문서형태 변환기능, 아직 덜 정의된 상태라고 함..)



1) XSLT


← 스타일시트 파일은 보통 하나 이상의 템플릿 룰로 구성되며 XML형식문서로서 <xsl:stylesheet> 앨리먼트를 루트앨리먼트로 갖는다.


2) XPath

: 특정 노드를 가리키기 위한 용도로 XSLT, XPointer 에서 사용됨.



위에서 사용된 match="books/book" 의 'books/book' , 'category'등은 모두 XPath 표현으로 특정위치에 있거나 특정조건을 만족하는 일부를 가리키는데 사용됨.

즉, 문서구조변환을 정의하는 핵심표현방식이다.



XPath 표현 및 함수를 통해 템플릿에 적용할 노드를 지정할 수 있다.



[샘플]

<?xml version="1.0" encoding="euc-kr"?>

<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version="1.0">

<xsl:template match="product">

<output name="{product_name}">

<output-code><xsl:value-of select="product_code"/></output-code>

<output-type><xsl:value-of select="@product_type"/></output-type>

</output>

</xsl:template>

</xsl:stylesheet>





① XML문서에서 'product-output' 앨리먼트를 찾는다.

그리고 해당 앨리먼트에 대해 Template 내용을 적용한다.

<output> 앨리먼트를 추가하고 그 하위에 <output-code>라는 새로운 앨리먼트를 추가한다.

② product_name 과 같이 Source Tree의 앨리먼트를 Result Tree문서의 속성값으로 쓸 경우에는 '{앨리먼트명}'와 같이 중괄호로 표현한다.

③ output-code는 그 값을 최초 match 태그를 통해 매치시킨 product-output 앨리먼트의 code값을 그 값으로 한다.

④ Product_type 과 같이 앨리먼트의 속성을 앨리먼트로 변경할 경우 '@속성명' 과 같이 표현한다.



XPath 표현에서 사용가능한 패턴



패턴 의미 적용예
/ 문서의 루트를 의미  
// 문서내 일치하는 모든 후손 노드(엘리먼트)를 의미 //code (문서 내 code라는 노드명을 가진 모든 노드)
. 현재 노드  
.. 현재 노드의 부모노드  
* 모든 노드  
@속성명 해당 속성  






[샘플]

<?xml version="1.0" encoding="euc-kr"?>

<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version="1.0">

<xsl:template match="/">

<output>

<xsl:for-each select="//name">

<output-code><xsl:value-of select="../product_code"/></output-code>

</xsl:for-each>

</output>

<products>

<xsl:for-each select="product/*">

<product><xsl:value-of select="."/></product>

</xsl:for-each>

</products>

</xsl:template>

</xsl:stylesheet>



문서 루트를 검색하여 앨리먼트명이 'name'인 것을 골라 그것의 코드명을 output-code 값으로 표시한다.



이렇게 Source tree XML문서를 Result Tree XML문서로 변경하는데 있어서, 모든 형태의 노드를 일일이 지정하지 않고 특정 조건에 맞는 노드들만 필터링 하여 Transformation시킬 수 있다.



필터링



● XPath 표현을 이용한 필터링



<?xml version="1.0" encoding="euc-kr"?>

<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version="1.0">

<xsl:template match="/">

<book>

<xsl:for-each select="/goods/books/book[option]">

<option>

<xsl:value-of select="book_option_name"/>

</option>

</xsl:for-each>

</book>

<cd>

<xsl:for-each select="/goods/cds/cd[option='one more' and price <= 20000 and proce >= 10000 and @type='single']>

<title>

<xsl:attribute name="poscode"><xsl:value-of selce="pcode"/></xsl:attribute>

<xsl:value-of select="ptitle"/>

</title>

</xsl:for-each>

</cd>

</xsl:template>

</xsl:stylesheet>



① good>books>book 중 옵션이 있는 노드만 추려서 출력

② 옵션값이 'one more'이고 값이 10,000원이상 20,000 이하인 것 중 타입이 '싱글앨범'인 건만 추려서 출력



그 외 논리 및 비교연산자 : or / != ...



● XPath 함수를 이용한 필터링



함수명 의미
Position() 현재 노드의 위치 반환
last() 전체노드멤버 개수 반환
count() 인수로 주어진 노드셋의 총개수 반환





<?xml version="1.0" encoding="euc-kr"?>

<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version="1.0">

<xsl:template match="/">




<cdbox>

<cd>

<xsl:apply-templates select="/goods/cdbox/cd[position()=2]"/>

</cd>

</cdbox>

</xsl:template>

</xsl:stylesheet>





① Source Tree의 두 번째 cd 앨리먼트를 가져온다.

간단하게 "/goods/cdbox/cd[2]"로도 표현식으로도 표현가능





이외 함수



- sum() 함수

<xsl:value-of select="sum(//price[../@type='single'])"/>

싱글앨범의 가격 합산

- format-number() 함수

<xsl:value-of select="format-number(sum(//price[../@type='single'],'#,###')"/>

싱글앨범의 가격합산을 천단위 표시하여 출력하는 XSLT 함수



2. XSLT를 이용한 XML문서의 변환



PHP5가 발표되면서 XML의 모든 확장기능을 libxml2 라이브러리로 재설계됨.

(SAX, DOM 파서, XSLT프로세서까지 libxml2 표준라이브러리를 기준으로 모두 새롭게 개발됨)



[샘플]



<?

//스타일시트 문서를 DOMDocument 객체형태로 가져온다.

$xsl = new DOMDocument();

$xsl->load("transformation.xsl");



//XML 문서를 DOMDocument 객체형태 가져온다

$xml = new DOMDocument();

$xml->load("sample.xml");



//XSLT 프로세스 생성, XML 문서에 적용할 스타일시트 문서 호출

$XSLTProc = new XSLTProcessor();

$XSLTProc->importStylesheet($xsl);



//변환을 수행하고 결과 생성문서 저장

$doc=$XSLTProc->transformToDoc($xml);



//생성된 문서 인코딩 설정

$doc->encoding="euc-kr";



//문서의 소스 알아보기 쉽도록 포맷팅

$doc->formatOutput="TRUE";



//생성된 문서를 브라우저에 출력한다.

echo $doc->saveXML();

?>



변환 프로세스인 XSLTProcessor 클래스 객체의 주요 메소드



함수명 의미
importStylesheet() 소스트리에 적용할 스타일시트 파일 가져옴
transformToDoc() XSLT 변환 수행 후 결과를 DOM 객체로 반환
transformToXML() XSLT 변환 수행 후 결과를 문자열 데이터로 반환
transformToURI() XSLT 변환 수행 후 결과를 외부의 파일로 저장
setParameter() 스타일 시트에서 선언한 매개변수의 값을 설정
getParameter() setParameter() 메소드에 의해 설정된 매개변수의 값 반환




$xsl=new DOMDocument();

$xsl->load("sample.xsl");

$XSLTProc = new XSLTProcessor();

$XSLTProc->importStylesheet($xsl);



xsl 스타일시트 문서를 이용하여 변환하려면 우선 스타일시트 문서를 DOM도큐먼트객체로 생성 후 해당 객체를 인자로 XSLTProcessor 객체를 호출해야 한다.

이때 이 내용을 두줄로 줄일 수 있다.



$XSLTProc=new XSLTProcessor();

$XSLTProc->importStylesheet(DOMDocument::load("sample.xsl"));



$XSLTProc->transformToUri($xml,"toSample.xml");



$XSLTProc->setParameter("","bookName",iconv("EUC-KR","UTF-8","서적/제목"));





3. SimpleXML



처리지시문,주석,엔티티 등의 요소 외 앨리먼트의 데이터 및 속성을 다루고자 할 경우 간단하게 사용할 수 있는 XML 처리기



있다가 정리 ..