XSLT에서 스타일시트 선언 외부 함수 사용
API를 사용하는 스타일시트에서 함수에 Java™ 메소드를 바인드하는 방법의 대안으로, Java 외부 함수를 스타일시트에서 직접 선언할 수 있습니다. 스타일시트 실행 중 클래스 경로에 바인드된 Java 클래스를 존재하게 하려는 경우 하나의 추가 구성만 필요합니다.
프로시저
Java 확장 요소를 사용하여
Java 클래스에 접두부를 바인드할 수 있습니다.
<xltxe:java-extension
prefix = string
class = string />
참고: 접두부 이름은
http://www.ibm.com/xmlns/prod/xltxe-j 네임스페이스에
바인드되어 있는 경우 Java 확장 요소에 대해 사용 가능합니다.
Java 클래스에
접두부를 바인드한 후에 바인드된 클래스 내 메소드는 쉼표로 분리된
접두부 및 메소드 이름을 지정하여 호출할 수 있습니다.
prefix:methodName(Params*)
예
정적 메소드 호출
스타일시트 선언 외부 함수를
사용하는 XSLT 스타일시트를 준비하는 경우
Java 클래스 바인딩에
대한 접두부를 선언하십시오.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xltxe="http://www.ibm.com/xmlns/prod/xltxe-j"
xmlns:calc="http://com.example/myApp/calculator"
xmlns:sf="http://com.example/myApp/standardFormat">
<xltxe:java-extension prefix="calc" class="org.company.Calculator"/>
<xltxe:java-extension prefix="sf" class="org.standards.Formatter"/>
<xsl:template match="/">
<xsl:value-of select="sf:format(calc:sqrt(64), 'ISO-42.7')"/>
</xsl:template>
</xsl:stylesheet>
이 스타일시트는 xsltSource 소스
오브젝트를 통해 사용 가능하다고 가정하고 다음 코드는 스타일시트를 준비합니다.
// Create the factory
XFactory factory = XFactory.newInstance();
// Create an XSLT executable for the stylesheet
XSLTExecutable executable = factory.prepareXSLT(xsltSource);
다음
코드는 예제에 준비된 스타일시트를 실행합니다.
// Create the xml input
String xml = "<doc/>";
// Create a result object to store the transformation result
Result result = new StreamResult(System.out);
// Execute the XSLT executable
executable.execute(new StreamSource(new ByteArrayInputStream(xml.getBytes())), result);
제공된 스타일시트 예제에서는 org.company.Calculator 클래스가 하나의 매개변수를 사용하는 정적 메소드 sqrt()를 포함하고 org.standards.Formatter 클래스가 두 개의 매개변수를 사용하는 정적 메소드 format()을 포함한다고 가정합니다. 준비 시점에서 클래스 경로에는 클래스가 필요하지 않지만 스타일시트 실행 중에는 필요합니다.
다음은 org.company.Calculator 및 org.standards.Formatter
클래스의 구현 예제입니다.
package org.company;
public class Calculator {
public static int sqrt(int val) {
return (int)Math.sqrt(val);
}
}
package org.standards;
public class Formatter {
public static String format(int val, String pattern) {
return "Formatting " + val + " using pattern " + pattern;
}
}
인스턴스 메소드 호출
클래스에서 인스턴스 메소드를
호출하는 방법은 인스턴스 오브젝트에 대한 요구사항 때문에 정적 메소드 호출 방법과 조금
다릅니다.
스타일시트 내 Java
클래스에서 인스턴스 오브젝트를 확보하려면 새 생성자를 호출해야 합니다.
prefix:new(Params*)
이제 다음
스타일시트에서 보여주는 대로, xsl:variable 요소에 결과를 저장할 수 있습니다.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xltxe="http://www.ibm.com/xmlns/prod/xltxe-j"
xmlns:car="http://com.example/myApp/car">
<xltxe:java-extension prefix="car" class="org.automobile.Car"/>
<xsl:variable name="var" select="car:new(3)"/>
<xsl:template match="/">
<xsl:value-of select="car:getDoors($var)"/>
</xsl:template>
</xsl:stylesheet>
이 스타일시트는 xsltSource 소스
오브젝트를 통해 사용 가능하다고 가정하고
다음 코드는 스타일시트를 준비합니다.
// Create the factory
XFactory factory = XFactory.newInstance();
// Create an XSLT executable for the stylesheet
XSLTExecutable executable = factory.prepareXSLT(xsltSource);
다음
코드는 예제에 준비된 스타일시트를 실행합니다.
// Create the xml input
String xml = "<doc/>";
// Create a result object to store the transformation result
Result result = new StreamResult(System.out);
// Execute the XSLT executable
executable.execute(new StreamSource(new ByteArrayInputStream(xml.getBytes())), result);
스타일시트 예제에서는 org.automobile.Car 클래스가 int 유형의 인수를 사용하는 생성자를 포함한다고 가정합니다. 또한 org.automobile.Car 클래스는 인수를 사용하지 않는 인스턴스 메소드 getDoors()도 포함합니다. 스타일시트 선언 외부 함수에서 인스턴스 메소드를 호출하는 구문에서는 첫 번째 인수로 작성된 인스턴스 오브젝트가 전달되어야 합니다.
다음은 org.automobile.Car 클래스의 구현
예제입니다.
package org.automobile;
public class Car {
private int doors;
public Car (int doors) {
this.doors = doors;
}
public int getDoors() {
return doors;
}
}
인스턴스 메소드를 통한 상속도 지원됩니다.
org.automobile.Car 클래스에 서브클래스 org.automobile.Sedan이 있으면
org.automobile.Sedan 클래스의 인스턴스를 작성하고 이를 사용하여
org.automobile.Car에서 메소드를 호출할 수 있습니다. 이는 다음 스타일시트로 설명합니다.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xltxe="http://www.ibm.com/xmlns/prod/xltxe-j"
xmlns:sedan="http://com.example/myApp/sedan"
xmlns:car="http://com.example/myApp/car">
<xltxe:java-extension prefix="sedan" class="org.automobile.Sedan"/>
<xltxe:java-extension prefix="car" class="org.automobile.Car"/>
<xsl:variable name="var" select="sedan:new(5)"/>
<xsl:template match="/">
<xsl:value-of select="car:getDoors($var)"/>
</xsl:template>
</xsl:stylesheet>
다음은 org.automobile.Sedan에 대한
구현 예제입니다.
package org.automobile;
public class Sedan extends Car {
public Sedan (int doors) {
super(doors);
}
}
제한사항: Java 클래스에서 메소드를 확인하는 데
사용되는 메커니즘에서는 이름 및 인수 수가 일치하는 하나의 메소드만 있어야 합니다.
이름은 같지만 인수 수가 다른 메소드가 여러 개 있으면 오류가 발생합니다.