XSL : 시퀀스가 항상 비어 있지 않습니까?
-
11-09-2019 - |
문제
이 스타일 시트의 출력을 이해하지 못합니다.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="root/sub"/>
</xsl:template>
<xsl:template match="sub">
<xsl:variable name="seq">
<xsl:sequence select="*" />
</xsl:variable>
<xsl:message>
<xsl:value-of select="@id" />
<xsl:text>: </xsl:text>
<xsl:value-of select="count($seq)" />
</xsl:message>
</xsl:template>
</xsl:stylesheet>
다음 XML에 적용 할 때 :
<root>
<sub id="empty" />
<sub id="one"><one/></sub>
<sub id="two"><one/><one/></sub>
<sub id="three"><one/><one/><one/></sub>
</root>
출력, 작성 xsl:message
요소, IS :
empty: 1
one: 1
two: 1
three: 1
나는 대신 이것을 기대했다 :
empty: 0
one: 1
two: 2
three: 3
왜 count($seq)
이 경우 항상 1을 반환합니까? 가변 정의를 어떻게 변경하여 나중에 공허함을 테스트 할 수 있습니까? (단순한 <xsl:variable name='seq' select='*' />
예상 대답을 반환하지만 선택 사항이 아닙니다 ... 변경하고 싶습니다. between
변수 이 템플릿, 나중에 공허함을 테스트하십시오).
해결책
귀하의 질문의 "이유"에 대답하려고 노력하겠습니다.
다음 진술을 작성하는 경우 :
<xsl:variable name="x" select="*" />
변수 $x
현재 노드의 하위 노드 시퀀스를 포함합니다. 암시 적 부모 노드가 없습니다 $x
, 당신은 사용하기 때문에 select
. 이제 다음을 고려하십시오.
<xsl:variable name="x">
<content />
<content />
</xsl:variable>
여기서 변수 $x
하나의 노드 시퀀스를 포함합니다 : 부모 노드 content
. 여기, count($x)
항상 당신에게 줄 것입니다 1
. 금액을 얻으려면 content
요소, 당신은 $x
암시 적 루트 노드 : count($x/content)
.
일반적으로 다음을 기억할 수 있습니다. 만약에 xsl:variable
그 자체는 a를 가진 빈 요소입니다 select
속성, 결과 세트는 변수에 할당됩니다. 사용하는 경우 xsl:variable
없이 select
속성, 당신은 항상 변수를 가진 암시 적 부모를 생성하고 변수의 내용은 그 아래의 어린이입니다..
예제에도 동일하게 적용됩니다 xsl:sequence
어린 시절 xsl:variable
. 비어 있지 않음으로써 xsl:variable
당신은 시퀀스에 대한 암시 적 부모를 만듭니다. 그래서 당신은 항상 얻는 이유입니다. 1
변수 자체를 계산하는 경우.
둘 다 필요한 경우 : 내부의 진술 묶음 xsl:variable
, 그러나 행동의 행동 select
속성, 다음을 사용하여이를 해결할 수 있습니다.
<xsl:variable name="x" select="$y/*" />
<xsl:variable name="y">
<xsl:sequence select="foo" />
</xsl:variable>
이제 예상 금액을 산출합니다 count($x)
, 그러나 그것이 정말로 유익한 지 또는 코드를 더 명확하게 만드는지 여부는 논쟁의 여지가 있습니다.
다른 팁
변수 선언을 변경하면 다음으로 예상되는대로 작동합니다.
<xsl:variable name="seq" select="*"/>
또는 'as'속성을 사용하여 변수의 유형을 선언합니다.
<xsl:variable name="seq" as="item()*">
<xsl:sequence select="*" />
</xsl:variable>
XSLT 2.0의 놀라운 결과에 대한 유형 정보를 지정하지 않으면 종종 리즈가 있습니다. Saxon을 사용하는 경우 Saxon이 설명 속성을 사용하여 스타일을 해석하는 방법을 출력 할 수 있습니다.
<xsl:template match="sub" saxon:explain="yes" xmlns:saxon="http://saxon.sf.net/">
<xsl:variable name="seq">
<xsl:sequence select="*" />
</xsl:variable>
<xsl:message>
<xsl:value-of select="@id" />
<xsl:text>: </xsl:text>
<xsl:value-of select="count($seq)" />
</xsl:message>
</xsl:template>
보시다시피, Saxon은 서열에서 문서 노드를 구성합니다.
Optimized expression tree for template at line 6 in :
let $seq[refCount=1] as document-node() :=
document-constructor
child::element()
return
message
하위 노드를 선택한 다음 각 노드를 계산하고 있으므로 항상 1이됩니다. 예를 들어 어린이를 계산해야합니다.
<xsl:value-of select="count($seq/*)" />
당신이 기대하는 출력을 줄 것입니다.