2009-10-10 4 views
1

나는 이것에 대한 답을 알고 있다고 생각하지만, 나는이 사실을 올바르게 이해하고 있다는 확인을 원한다.apply-templates가 명시 적으로 호출되지 않으면 XSLT가 현재 노드의 자식 노드를 처리하지 않는 것이 맞습니까?

XSLT 템플릿이 일치하여 실행될 때 은 현재 노드의 하위 노드 (일치하는 템플릿이 실행되는 노드 현재)가 기본적으로 처리되지 않습니다. "apply-templates"를 호출하여 프로세서가 현재 (일치하는) 노드의 하위 노드로 이동하도록해야합니다. 동안

<person> 
    <firstName>Deane</firstName> 
    <lastName>Barker</lastName> 
</person> 

변환이, XSLT 프로세서가 "사람"요소에서 시작 :

이 XML을 고려하십시오. 템플릿을 찾으면 템플릿을 실행하지만 템플릿을 찾기 위해 "firstName"및 "lastName"요소로 내려갑니다. "apply-templates"가 "person"에 대한 템플릿에서 명시 적으로 호출되는 경우에만 수행됩니다. 이 경우

<!-- Template #1 --> 
<xsl:template match="person"> 
    I found a "person" element 
</xsl:template> 

<!-- Template #2 --> 
<xsl:template match="firstName"> 
    I found a "firstName" element 
</xsl:template> 

, 올바른 실행되지 않습니다 # 2 틀 :

이 XSL을 고려? XML 문서의 순회는 "person"엘리먼트를 치고, Template # 1을 찾고, 실행 한 다음 결코 "person"의 자식으로 내려 가지 않습니다. 나는이에 대한 첫 번째 템플릿을 변경하는 경우

-

<!-- Template #1 --> 
<xsl:template match="person"> 
    I found a "person" element 
    <xsl:apply-templates select="firstName"/> 
</xsl:template> 

만 다음 # 2 실행하는 서식합니다. 내가 이것을 정확히 이해하고 있는가?

답변

4

지금까지 두 답변에 동의했습니다. 템플릿 # 2가 정확하게 처리되지 않는다는 평가가 정확합니다.

노드의 하위 노드 (예 :,

  1. select 속성의 기본값은 "node()"입니다 어린이를 선택하는 XPath를, 그리고 : 자식 요소, 주석, 텍스트, 처리 명령,하지만 하지 속성) 두 가지 방법으로 만 특별하다
  2. 루트 노드와 요소 노드에 대한 기본 제공 템플릿 규칙은 자식을 처리하는 것입니다.

두 가지 측면 이외에, 어린이는 처리 할 노드를 선택할 때 특별한 상태가 없습니다. 조상을 포함하여 원하는 노드를 선택할 수 있습니다. 원하는 순서대로 나무를 탐색 할 수 있습니다. 이를 증명하는 극단적 인 방법은 문서의 계층 구조를 뒤바꾸는 스타일 시트를 쓰는 것입니다 (거꾸로 뒤집습니다). 자식 노드가 처리 될 때보 다 부모 노드가 처리 될 때 다른 규칙이 호출되도록 다른 모드를 사용하고 싶을 것입니다.

또한 "루트 노드 (루트 노드)"와 " "(XPath/XSLT 2.0에서"문서 노드 "로 이름 변경) 및 루트 (또는 문서) 요소. 예제 XML에서 < 사람은>이 아니며 루트 노드입니다. 바깥 쪽 요소입니다. 루트 노드의 자식 인 XPath/XSLT 데이터 모델의 모든 트리 루트에있는 보이지 않는 외부 컨테이너입니다.

배트의 오른쪽 처리를 제어하려면 < xsl : template match = "/"> 또는 (소스 트리가 조각이 아닌 올바른 형식의 XML 문서를 나타낼 경우) < xsl : template match = "/ *">를 입력하십시오. 그것들은 대체 방법입니다. 후자의 기능 중 하나는 명시 적 템플릿 규칙 (가져 오기 우선 순위가 가장 낮더라도)이 항상 기본 제공 템플릿 규칙보다 우선하므로 match = "/"에 대한 규칙을 포함하는 가져온 코드가 먼저 트리거된다는 것입니다. 가져 오기 스타일 시트에 명시 적으로 < xsl : template match = "/">이 없으면 루트 노드에 대한 기본 제공 템플릿 규칙을 사용하는 코드를 가져올 때까지 children -이 경우, 템플릿을 < person> 요소 자식에게 적용).

이 예제의 경우 배트를 제어하는 ​​다른 방법은 match = "/ person"을 사용하는 것입니다. 이 규칙은 루트 노드의 하위 요소 인 경우 모든 < person> 요소와 일치합니다. XML에 < person>이 가장 바깥 쪽 요소로없는 경우에는 호출되지 않습니다. 그리고 < xsl : template match = "/"가 있으면 먼저 호출됩니다. match = "/ person"(또는 match = "/ *")는 명시 적으로 템플릿을 자식에게 적용한 match = "/"규칙 인 경우에만 호출됩니다.

2

네, 맞습니다. 트리를 추가로 탐색하려면 apply-templates를 명시 적으로 호출해야합니다. 항상 더 일반적인 <xsl:apply-templates /> (@select없이)을 사용하여 모든 자식 노드에 템플릿을 적용 할 수 있습니다 (해당 요소의 속성은 select = "@ *"를 사용하여 명시 적으로 선택해야 함).

그러나 <xsl:copy-of select="person" />을 사용하면 선택된 요소와 모든 하위 요소를 직접 복사하는 등의 작업을 수행 할 수 있습니다.

+0

Nitpicking :'@ xsl : apply-templates />'(@select없이) 템플릿이 요소가 아닌 모든 하위 * 노드 *에 적용됩니다 (자식으로 취급되지 않는 속성 제외). – Tomalak

+0

이 버그 (http://meta.stackexchange.com/questions/18360/vote-too-old-to-be-changed-but-i-havent-voted)로 인해 답변을 얻을 수 없습니다. . 죄송합니다. – Tomalak

+0

고마워, 나는 실수했다. –

1

네, 맞습니다. 이미 알고 있듯이, 그것은 또한 apply-templates 로직에 "입력"하는 방법에 달려 있습니다. 위의 예에서 "person"에 대한 템플리트가 없으면 기본 템플리트 규칙이 실행되었을 것입니다 (apply-templates가 호출 된 지점의 모든 하위 노드에 대해).

그러나 apply-templates 호출에서 자식 노드와 일치하는 템플릿 중 하나라도 스타일 시트에 정의되어 있으면 해당 노드의 자식 노드에 템플릿을 적용하는 것이 apply-templates를 다시 호출하는 템플릿에 의해 지정됩니다. 그들은 무시 될 것입니다.

관련 문제