[xslt] XSLT에서 문자열이 null인지 또는 비어 있는지 확인

XSL 에서 값이 null인지 또는 비어 있는지 어떻게 확인할 수 있습니까?

예를 들어 categoryName비어 있다면 ? 구문을 선택할 때를 사용하고 있습니다.

예를 들면 다음과 같습니다.

<xsl:choose>
    <xsl:when test="categoryName !=null">
        <xsl:value-of select="categoryName " />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="other" />
    </xsl:otherwise>
</xsl:choose>



답변

test="categoryName != ''"

편집 : 이것은 의사 코드와 XSLT에 대한 내 자신의 초기 경험을 포함하여 질문에서 유추 한 “null 또는 empty가 아님”에 대한 가장 가능성있는 해석을 다룹니다. 즉, “다음 Java와 동등한 것은 무엇입니까?”:

!(categoryName == null || categoryName.equals(""))

예를 들어 null과 빈을 명확하게 식별하는 자세한 내용은 아래의 johnvey의 답변 및 / 또는 해당 답변에서 수정 한 XSLT ‘fiddle’을 참조하십시오 . 여기에는 Michael Kay의 의견에있는 옵션과 가능한 여섯 번째 해석이 포함됩니다.


답변

다른 정보가 없으면 다음 XML을 가정합니다.

<group>
    <item>
        <id>item 1</id>
        <CategoryName>blue</CategoryName>
    </item>
    <item>
        <id>item 2</id>
        <CategoryName></CategoryName>
    </item>
    <item>
        <id>item 3</id>
    </item>
    ...
</group>

샘플 사용 사례는 다음과 같습니다.

<xsl:for-each select="/group/item">
    <xsl:if test="CategoryName">
        <!-- will be instantiated for item #1 and item #2 -->
    </xsl:if>
    <xsl:if test="not(CategoryName)">
        <!-- will be instantiated for item #3 -->
    </xsl:if>
    <xsl:if test="CategoryName != ''">
        <!-- will be instantiated for item #1 -->
    </xsl:if>
    <xsl:if test="CategoryName = ''">
        <!-- will be instantiated for item #2 -->
    </xsl:if>
</xsl:for-each>


답변

에서 빈 요소 :

특정 노드의 값이 비어 있는지 테스트하려면

그것은 당신이 비어있는 의미에 달려 있습니다.

  • 자식 노드가 없습니다 : not(node())
  • 텍스트 내용이 없습니다 : not(string(.))
  • 공백 이외의 텍스트를 포함하지 않습니다. not(normalize-space(.))
  • 주석 외에는 아무것도 포함하지 않습니다 : not(node()[not(self::comment())])

답변

이건 어떤가요?

test="not(normalize-space(categoryName)='')"


답변

처음 두 개는 null 값을 처리하고 두 번째 두 개는 빈 문자열을 처리합니다.

<xsl:if test="USER/FIRSTNAME">
    USERNAME is not null
</xsl:if>
<xsl:if test="not(USER/FIRSTNAME)">
    USERNAME is null
 </xsl:if>
 <xsl:if test="USER/FIRSTNAME=''">
     USERNAME is empty string
 </xsl:if>
 <xsl:if test="USER/FIRSTNAME!=''">
     USERNAME is not empty string
 </xsl:if>


답변

경우에 따라 값이 구체적으로 null 인시기를 알고 싶을 수 있습니다. 이는 .NET 객체에서 직렬화 된 XML을 사용할 때 특히 필요합니다. 허용 된 답변 이이 작업을 수행하는 동안 문자열이 비어 있거나 비어있을 때 동일한 결과를 반환합니다 (예 : ”). 그래서 구별 할 수 없습니다.

<group>
    <item>
        <id>item 1</id>
        <CategoryName xsi:nil="true" />
    </item>
</group>

따라서 속성을 간단히 테스트 할 수 있습니다.

<xsl:if test="CategoryName/@xsi:nil='true'">
   Hello World.
</xsl:if>

때로는 정확한 상태를 알아야 할 필요가 있으며 Javascript와 달리 CategoryName이 인스턴스화되었는지 간단히 확인할 수 없습니다.

<xsl:if test="CategoryName">
   Hello World.
</xsl:if>

널 요소에 대해서는 true를 리턴합니다.


답변

나는이 질문이 오래되었다는 것을 알고 있지만 모든 답변 사이에서 XSLT 개발 에서이 유스 케이스에 대한 일반적인 접근법 중 하나를 그리워합니다.

OP에서 누락 된 코드는 다음과 같습니다.

<xsl:template match="category">
    <xsl:choose>
        <xsl:when test="categoryName !=null">
            <xsl:value-of select="categoryName " />
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="other" />
        </xsl:otherwise>
    </xsl:choose>
</category>

입력은 다음과 같습니다.

<categories>
    <category>
       <categoryName>Books</categoryName>
    </category>
    <category>
       <categoryName>Magazines</categoryName>
       <categoryName>Periodicals</categoryName>
       <categoryName>Journals</categoryName>
    </category>
    <category>
        <categoryName><!-- please fill in category --></categoryName>
    </category>
    <category>
        <categoryName />
    </category>
    <category />
</categories>

즉, 0, 비어 있거나 단일 또는 여러 categoryName요소 가있을 수 있다고 가정 합니다. xsl:choose-style 구문을 사용하여 즉, 요소가 다른 레벨에있을 수있는 경우에도 더 복잡해집니다. XSLT의 일반적인 프로그래밍 관용구는 템플릿 (따라서 XSLT의 T)을 사용하는 것입니다. 이는 선언적인 프로그래밍이 아니라 명령적인 것이 아닙니다 (프로세서에 지시하지 않고 특정 조건이 충족되는 경우 출력하고자하는 것을 알려줍니다). 이 사용 사례의 경우 다음과 같이 보일 수 있습니다.

<!-- positive test, any category with a valid categoryName -->
<xsl:template match="category[categoryName[text()]]">
    <xsl:apply-templates />
</xsl:template>

<!-- any other category (without categoryName, "null", with comments etc) -->
<xsl:template match="category">
    <xsl:text>Category: Other</xsl:text>
</xsl:template>

<!-- matching the categoryName itself for easy handling of multiple names -->
<xsl:template match="categoryName">
    <xsl:text>Category: </xsl:text>
    <xsl:value-of select="." />
</xsl:template>

위의 첫 번째 버전이 우선 순위가 높기 때문에 (모든 XSLT 버전에서) 작동합니다. “fall-through”일치 템플릿 인 두 번째 템플릿은 유효하지 않은 것을 포착합니다. 그런 다음 세 번째 categoryName는 올바른 방식으로 값 을 출력합니다 .

이 시나리오에서는 달리 명시하지 않는 한 프로세서가 모든 하위 항목을 자동으로 처리하기 때문에 categories또는이 항목을 명시 적으로 일치시킬 필요 category가 없습니다 xsl:apply-templates. 그들).

이 접근 방식은 여러 범주를 자동으로 처리하고 다른 일치하는 템플릿을 추가하여 다른 요소 또는 예외에 대해 확장 할 수 있기 때문에 명령 방식보다 확장 성이 뛰어납니다. if-branches가없는 프로그래밍 .

참고 : nullXML 과 같은 것은 없습니다 . 이 XSI : 전무는 하지만 거의 어떤 종류의 스키마없이 형식화되지 않은 상황에서, 특히 거의 사용되지 않는다.