2006년 7월 30일 일요일

XSLT를 통한 문서변환

출처 : http://blog.naver.com/cowboy0626/30002011217

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 &lt;= 20000 and proce &gt;= 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 처리기

 

있다가 정리 ..

댓글 없음:

댓글 쓰기