2012-02-09 4 views
2

비교와-PARAM의 Xalan-J와 색슨와 나는 자바 코드에서 XSLT 1.0을 사용하는 방법을 배울 최선을 시도하고 있지만, 내 마음의 비트를 풀어 시작입니다 시간이 지남에 천천히 조금씩.예기치 않은 동작 : 적용 템플릿/XSL : xsltproc

Xalan-J (모든 종속성 jar와 함께 xalan.jar 및 xsltc.jar), saxon 및 jing (내 프로젝트에서 후자 두 개는 내 프로젝트에서 elswhere로 사용됩니다)이 내 클래스 경로에 있고 JAXP를 System .setProperty는 내가 원하는 방식으로 TransformerFactory와 같은 클래스 구현을 사용하도록 강제합니다. 또한 코드에서 속성을 변경하기 만하면 여러 XSLT 프로세서가 단일 XSL 변환 파일을 사용하여 어떻게 작동하는지 확인할 수 있습니다. 또한 cygwin 환경에서 xsltproc을 사용하여 어떤 일이 일어나는지 확인합니다. 나는 또한 내 Java 코드가 문제가 아닌지 확인하기 위해 Oxygen에서 디버그한다.

이 더미 XSL을 살펴 보자

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     
       xmlns:rng="http://relaxng.org/ns/structure/1.0" 
       xmlns:ex="http://example.com/ns/ex" 
       version="1.0"> 

    <xsl:output method="xml" encoding="utf-8"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/"> 
    <!-- Start by finding the root grammar element --> 
    <xsl:apply-templates select="rng:grammar"/> 
    </xsl:template> 

    <xsl:template match="/rng:grammar"> 
    <!-- Continue with child grammar elements --> 
    <xsl:apply-templates select="descendant::rng:grammar"/> 
    </xsl:template> 

    <xsl:template match="rng:grammar"> 
    <!-- set the variable and pass it's value to another template --> 
    <xsl:variable name="parameter" select="'any-string-value'"/> 
    <xsl:message>initial value: <xsl:value-of select="$parameter"/></xsl:message> 
    <xsl:apply-templates select="descendant::ex:data"> 
     <xsl:with-param name="parameter" select="$parameter"/> 
    </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="rng:optional"> 
    <!-- use the param value here --> 
    <xsl:param name="parameter"/> 
    <xsl:message>final value: <xsl:value-of select="$parameter"/></xsl:message> 
    </xsl:template> 

</xsl:stylesheet> 

그것은이 더미 XML 인스턴스 문서 작업을 몇 가지 템플릿을 호출 제외하고 아무것도하지 않는다 :

<?xml version="1.0" encoding="UTF-8"?> 
<grammar 
    xmlns="http://relaxng.org/ns/structure/1.0" 
    xmlns:ex="http://example.com/ns/ex" 
    datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> 
    <start> 
    <grammar ex:subgram="something" ns="http://example.com/ns/something"> 
     <start> 
     <ex:data> 
      <optional /> 
     </ex:data> 
     </start> 
    </grammar> 
    </start> 
</grammar> 

내가 '모르는를 잘못하고 있지만 xsltc와 xsltproc에서만 XSL의 유일한 변수 값을 전달합니다. 정상적인 xalan과 saxon은 모두 값을 전달하지 못합니다. 아래 결과를보십시오.

xsltproc :

$ xsltproc transformation.xsl instance.xml 
initial value: any-string-value 
final value: any-string-value 

Xalan에 컴파일 처리부 (XSLTC 또한 자바 1.6 기본 구현)

Implementation: org.apache.xalan.xsltc.trax.TransformerFactoryImpl loaded from: ./lib/xalan-j_2_7_1/xsltc.jar 
initial value: any-string-value 
final value: any-string-value 

Xalan에 통역 프로세서 (Xalan에)

Implementation: org.apache.xalan.processor.TransformerFactoryImpl loaded from: ./lib/xalan-j_2_7_1/xalan.jar 
initial value: any-string-value 
final value: 

슨 :

Implementation: com.icl.saxon.TransformerFactoryImpl loaded from: ./lib/saxon6-5-5/saxon.jar 
initial value: any-string-value 
final value: 

나는이의 Xalan (이유는 허용 EXSLT 지원되는)와 함께 작동하도록해야합니다. 다른 산출물에 대한 이유가 무엇인지 모릅니다. 나는이 모든 프로세서가 XSLT 1.0을 구현하도록 강요하지만 그들은 다르게 처리한다고 생각한다. 내 XSL에서 XSLT 1.0을 준수하지 않으려 고 노력하고 있습니까? 이 방법을 사용할 수있는 해결 방법이 있습니까?

답변

2

설명은 간단하다 :

<xsl:template match="rng:optional"> 
    <!-- use the param value here --> 
    <xsl:param name="parameter"/> 
    <xsl:message>final value: <xsl:value-of select="$parameter"/></xsl:message> 
    </xsl:template> 

rng:optionalex:data의 자식입니다.

따라서이 요소 노드를위한 템플릿 내장 XSLT에 의해 처리 될 어떠한 템플릿 matchin ex:data 없다.

내장 된 템플릿 물론, 여기에 전달되는 매개 변수에 대해 아무것도 모르는, 그래서 그것이 적용되는 다음 템플릿을 통과하지 않습니다.

따라서 요소에 대한 XSLT 기본 제공 템플릿에 의해 rng:optional (위)과 일치하는 템플릿이 선택되며 매개 변수가이 선택된 템플릿에 전달되지 않습니다.

따라서 parameter 매개 변수의 값은 빈 문자열이며 Saxon 및 XalanJ에서 올바른 출력을 얻습니다.

+0

사실 말이 맞습니다. xsltproc 및 xsltc 내장 템플릿은 매개 변수를 처리하는 것으로 보이지만 ... 휴대 XSL로 생각되는 것을 정반대로 만듭니다. – predi

+0

@predi : 해결책은 매개 변수가 선언 된'ex : data'와 일치하는 템플리트를 가지며'xsl : apply-templates' –

+0

yes를 통해 전달합니다. 누락 된 템플릿을 추가하면 매개 변수에는 해당 템플릿 내에서 가질 것으로 예상되는 값이 있습니다. 그 사이의 중간 부분이 당신에게 쓸모없는 경우에도 시작 지점과 목표 사이의 전체 "경로"를 통해 올바르게 위임되어야합니다. 매개 변수가 사용되는 경우 자손 축 또는 이와 유사한 요소로 모서리를 자르는 것은 no-no입니다. – predi