2017-10-07 8 views
2

this에 따르면 match에 대한 XPath 식의 매개 변수를 사용할 수 있어야합니다. 그러나 xsl:templatexsl:param을 동일한 템플릿에 사용하면 작동하지 않는 것 같습니다.XSLT 2.0의 일치하는 XPath 표현식에서 템플릿 매개 변수를 사용할 수 없습니까?

<?xml version="1.0" encoding="UTF-8"?> 
<myRoot> 
    <myNode myAttribute="3"> 
     <myChildAttribute myChildAttribute="a" /> 
    </myNode> 
    <myNode myAttribute="2"> 
     <myChildAttribute myChildAttribute="b" /> 
    </myNode> 
    <myNode myAttribute="1" /> 
</myRoot> 

과 같은 내 XSL 파일을 다음과 같이

내 XML 파일을 찾습니다. SAXON 9HE으로 실행할 때

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" encoding="UTF-8"/> 

    <xsl:template match="myRoot"> 
     <xsl:apply-templates select="myNode"> 
      <xsl:sort select="@myAttribute" /> 
      <xsl:with-param name="myParam" select="max(myNode/@myAttribute)" /> 
     </xsl:apply-templates> 
    </xsl:template> 

    <xsl:template match="myNode[node() and @myAttribute = $myParam]"> 
     <xsl:param name="myParam" /> 
      <xsl:for-each select="myChildAttribute"> 
INSERT INTO a(b) VALUES ('<xsl:value-of select="@myChildAttribute" />'); 
      </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 

불행하게도 같은 템플릿의 일치 XPath 식에 템플릿의 매개 변수를 사용할 수 없습니다 다음과 같은 오류

XPST0008: Variable myParam has not been declared (or its declaration is not in scope) 

로 끝! ?

답변

3

동일한 템플릿의 일치하는 XPath 표현에서 템플릿의 매개 변수를 사용할 수 있습니까?

없음 템플릿의 검색 식에 어떤 변수/파라미터가 범위 (정의/표시) 템플릿이 실행을 위해 선택된 경우이어야한다.

템플릿은 XSLT 지시문 (전역 수준에서 정의 됨)이므로 범위 내에있는 유일한 변수/매개 변수는 전역 수준 변수/매개 변수입니다.

템플릿의 매개 변수는 템플릿을 실행하기 전에 선택한 후에 만 ​​전달됩니다. 즉, 템플리트 선택 프로세스가 실행될 때이 매개 변수의 값이 존재하지 않습니다.

따라서 실행 프로세스의 템플릿 선택에 전역 외 표현식을 사용하려면이 표현식을 평가할 수있는 xsl:apply-templates 명령어의 select 속성에 제공해야합니다. match이 표현식을 평가할 수없는 템플리트의 속성.

이 명확하게하기 위해, 아래 코드는 제공된 코드에서 문제를 해결합니다

<myRoot> 
    <myNode myAttribute="3"> 
     <myChildAttribute myChildAttribute="a" /> 
    </myNode> 
    <myNode myAttribute="2"> 
     <myChildAttribute myChildAttribute="b" /> 
    </myNode> 
    <myNode myAttribute="1" /> 
</myRoot> 

:이 변환이 제공된 XML 문서에 적용

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
     <xsl:output method="text" encoding="UTF-8"/> 

     <xsl:template match="myRoot"> 
      <xsl:apply-templates select="myNode[@myAttribute = max(../myNode/@myAttribute)]"> 
       <xsl:sort select="@myAttribute" /> 
      </xsl:apply-templates> 
     </xsl:template> 

    <xsl:template match="myNode[node()]"> 
      <xsl:for-each select="myChildAttribute"> 
INSERT INTO a(b) VALUES ('<xsl:value-of select="@myChildAttribute" />'); 
      </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 

오류가 발생하지 않으며 이것은 변환의 출력입니다 (요구 사항 h가 없기 때문에 "올바른 출력"이라고 말할 수는 없습니다). ave가 정의되어 있으므로 검증 할 수 없습니다.그리고이 코드에 대한 내 예약이 있습니다. 예를 들어, 의 하위 사용은 의미가 없습니다. 동일한 (최대()) 값을 정렬하고 동일한 값의 시퀀스를 정렬하면 동일한 시퀀스가 ​​생성되기 때문입니다.

INSERT INTO a(b) VALUES ('a'); 
+1

감사합니다. Dimitre! 이제 나에게 분명하다. 'xsl : sort'는 변환의 이전 버전에서 남아 있습니다. 힌트를 가져 주셔서 감사합니다, 나는 그것을 제거합니다. – Jagger

2

나는 이것이 효과가 있다고 생각하지 않습니다. param은 정의한 템플릿 내에서 유효합니다. 그러나 일치 식은 실제로 템플릿의 일부가 아닙니다. myParam이 아직 정의되지 않은 경우 외부에서 평가해야합니다.

max (myNode/@ myAttribute)에 대한 필터링을 apply-templates 호출의 선택 식으로 이동해야합니다.