XSL에서 'call-template'과 'apply-templates'의 차이점은 무엇입니까?


119

저는 XSLT를 처음 사용하므로 두 태그에 대해 약간 혼란 스럽습니다.

<xsl:apply-templates name="nodes">

<xsl:call-template select="nodes"> 

그렇다면 그들 사이의 차이점을 나열 할 수 있습니까?

답변:


167

<xsl:call-template> 전통적인 프로그래밍 언어로 함수를 호출하는 것과 거의 동일합니다.

문자열을 출력하는이 간단한 함수처럼 XSLT에서 함수를 정의 할 수 있습니다.

<xsl:template name="dosomething">
  <xsl:text>A function that does something</xsl:text>
</xsl:template>

이 함수는를 통해 호출 할 수 있습니다 <xsl:call-template name="dosomething">.

<xsl:apply-templates>는 약간 다르며 XSLT의 진정한 힘입니다. XML 노드 ( select속성에 정의한 내용에 관계없이)를 여러 개 사용하고 반복 ( 중요 : apply-templates가 루프처럼 작동합니다! )하고 일치하는 템플릿을 찾습니다. 그들을 위해:

<!-- sample XML snippet -->
<xml>
  <foo /><bar /><baz />
</xml>

<!-- sample XSLT snippet -->
<xsl:template match="xml">
  <xsl:apply-templates select="*" /> <!-- three nodes selected here -->
</xsl:template>

<xsl:template match="foo"> <!-- will be called once -->
  <xsl:text>foo element encountered</xsl:text>
</xsl:template>

<xsl:template match="*"> <!-- will be called twice -->
  <xsl:text>other element countered</xsl:text>
</xsl:template>

이렇게하면 XSLT 프로세서에 대한 약간의 제어를 포기할 수 있습니다. 프로그램 흐름이 어디로 가는지 결정하는 것이 아니라 프로세서가 현재 처리중인 노드에 가장 적합한 일치 항목을 찾아서 수행합니다.

여러 템플릿이 노드와 일치 할 수있는 경우보다 구체적인 일치식이있는 템플릿이 우선합니다. 동일한 특이성을 가진 일치하는 템플릿이 둘 이상있는 경우 마지막으로 선언 된 템플릿이 승리합니다.

템플릿 개발에 더 집중할 수 있으며 "배관 작업"을 수행하는 데 더 적은 시간이 필요합니다. 프로그램은 더 강력하고 모듈화되고 덜 중첩되고 더 빨라질 것입니다 (XSLT 프로세서는 템플릿 일치에 최적화되어 있으므로).

XSLT로 이해해야 할 개념은 "현재 노드"의 개념입니다. <xsl:apply-templates>현재 노드를 사용 하면 모든 반복이 진행되지만 <xsl:call-template>현재 노드는 변경되지 않습니다. 즉, .호출 된 템플릿 내에서 호출 템플릿의 노드와 동일한 노드를 참조합니다 .. 적용 템플릿은 그렇지 않습니다.

이것이 기본적인 차이점입니다. 동작에 영향을 미치는 템플릿의 몇 가지 다른 측면이 있습니다. modepriority, 템플릿에 a namematch. 또한 템플릿을 가져 왔는지 ( <xsl:import>) 여부에 영향을 줍니다. 이것은 고급 사용이며 거기에 도착하면 다룰 수 있습니다.


5
@Tomalak : 좋은 대답입니다! 그러나 "xsl : apply-templates는 루프입니다"라는 문장은 올바르지 않습니다. <xsl:apply-templates>루프로 구현되어야 하는 공식 W3C 사양에는 표시가 없습니다 . 반대로 노드 목록의 서로 다른 노드에있는 서로 다른 응용 프로그램이 서로 완전히 독립적이기 때문에 병렬로 구현할 있습니다.
Dimitre Novatchev

8
@Dimitre : 내가 말하려는 것 : 최종 사용자의 관점에서 보면 <xsl:apply-templates>루프처럼 동작합니다. XSLT 프로세서의 구현 차이는 XSLT 프로그래머로서 저에게 영향을 미치지 않습니다. 결과는 병렬화 및 반복 구현 모두에서 완전히 동일합니다. 그러나 명령적인 배경을 가진 XSLT 초보자 <xsl:apply-templates>에게는 기술적으로는 그렇지 않더라도 일종의 for-each 루프 로 상상 하는 것이 도움이됩니다 .
Tomalak

@Tomalak : 이것은 초보자 XSLT 프로그래머에게 유용 할 수 있지만 "루프 실행"에서 축적 된 상태 정보를 재사용 할 수 있다고 생각하기 때문에 종종 오해의 소지가 있다고 생각합니다.
Dimitre Novatchev

@Tomalak는 이러한 사실 때문에, 나는 그것을 수정하는 것이 적절하다고 생각한다 "XSL을 : 적용 템플릿이 루프"와 같은 somethinkg와 "XSL : 적용 템플릿 것은 같은 루프"
Dimitre Novatchev

@Tomalak : 루프는 반복이며, 무언가 apply-templatescall-template지침은 아닙니다. XSLT의 재귀 메커니즘입니다. 그리고 Dimitre가 대답했듯이 apply-templates는 다형성 또는 데이터 기반 메커니즘입니다.

15

@Tomalak의 좋은 답변에 추가하려면 다음을 수행하십시오.

언급되지 않은 중요한 차이점은 다음과 같습니다 .

  1. xsl:apply-templates훨씬 풍부하고보다 더 깊은이며 xsl:call-templates, 심지어에서 xsl:for-each, 일반적인 경우에이 코드는 노드 목록의 서로 다른 노드에 대해 서로 다른 것 - 우리가 선택의 노드에 적용됩니다 어떤 코드를 모르는 단순히 때문이다.

  2. 적용될 코드는 xsl:apply templates가 작성된 후 원저자를 모르는 사람들 이 작성 하는 방식으로 작성할 수 있습니다 .

XSLT에 명령 이 없으면 FXSL 라이브러리 의 XSLT에서 고차 함수 (HOF)를 구현할 수 없습니다 <xsl:apply-templates>.

요약 : 템플릿과 <xsl:apply-templates>지침은 XSLT가 다형성을 구현하고 처리하는 방법입니다.

참조 : 전체 스레드를 참조하십시오 : http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/200411/msg00546.html


8

xsl:apply-templates일반적으로 (반드시 그런 것은 아님) 적용 가능한 모든 템플릿 을 사용하여 현재 노드의 하위 항목 전체 또는 하위 집합을 처리하는 데 사용됩니다 . 이것은 처리 된 XML의 (가능한) 재귀 성과 일치하는 XSLT 애플리케이션의 재 귀성을 지원합니다.

xsl:call-template반면에 일반적인 함수 호출과 훨씬 비슷합니다. 일반적으로 하나 이상의 매개 변수를 사용하여 정확히 하나의 (명명 된) 템플릿을 실행합니다.

그래서 xsl:apply-templates흥미로운 노드의 처리를 가로 채고 (보통) 출력 스트림에 무언가를 주입하려면 사용합니다. 일반적인 (간단한) 예는 다음과 같습니다.

<xsl:template match="foo">
  <bar>
    <xsl:apply-templates/>
  </bar>
</xsl:template>

와 반면에 xsl:call-template아무것도 당신을위한 전문, 재사용 가능한 기능을 작성합니다 - 나는 일반적으로 텍스트 또는 다른 nodesets로 선택 nodesets 변환과 같이, 함께 일부 하위 노드의 텍스트를 추가하는 등의 문제를 해결한다.

편집하다:

특정 질문 텍스트에 대한 추가 설명 :

<xsl:call-template name="nodes"/> 

이것은 'nodes'라는 템플릿을 호출합니다.

    <xsl:template name="nodes">...</xsl:template>

이것은 다음과 다른 의미입니다.

<xsl:apply-templates select="nodes"/>

... 이름이 'nodes'인 현재 XML 노드의 모든 자식에 모든 템플릿을 적용합니다.


2

기능은 실제로 유사합니다 ( 속성 및 해당 이름 템플릿이 call-template필요한 호출 의미 체계는 제외 name).

그러나 파서는 같은 방식으로 실행되지 않습니다.

에서 MSDN :

달리 <xsl:apply-templates>, <xsl:call-template>현재 노드 또는 현재 노드 목록을 변경하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.