Проверьте, является ли строка пустой или пустой в XSLT



Как я могу проверить, если значение равно null или пусто с XSL?



например, если 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>
1944   14  

14 ответов:

test="categoryName != ''"

Edit: это охватывает наиболее вероятную интерпретацию, на мой взгляд, "[not] null или empty", как следует из вопроса, в том числе это псевдокод и мой собственный ранний опыт работы с XSLT. Т. е., " Что такое эквивалент следующей Java?":

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

для получения более подробной информации, например, отчетливо идентифицируя null против empty, см. ответ джонви ниже и/или XSLT 'скрипка' я адаптировался из этого ответа, который включает в себя вариант в комментарии Майкла Кея, а также шестая возможная интерпретация.

отсутствие какой-либо другой информации, я буду считать следующий 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)='')"

первые два имеют дело с нулевым значением, а вторые два-с пустой строкой.

<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, что особенно необходимо при использовании XML, который был сериализован из объектов .NET. Хотя принятый ответ работает для этого, он также возвращает тот же результат, когда строка пуста или пуста, т. е.", поэтому вы не можете различать.

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

Так что вы можете просто проверить атрибут.

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

иногда необходимо знать точное состояние и вы не можете просто проверить, если CategoryName создается, потому что в отличие от say Javascript

<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>

т. е., я предполагаю, что может быть ноль, пустой, один или несколько categoryName элементы. Чтобы справиться со всеми этими случаями, используя xsl:choose - конструкции стиля, или в другом слова, императивно, быстро становятся грязными (тем более, если элементы могут быть на разных уровнях!). Типичная идиома программирования в XSLT использует шаблоны (следовательно, T в XSLT), что является декларативным программированием, а не императивным (вы не говорите процессору, что делать, вы просто говорите, что вы хотите вывести, если выполняются определенные условия). Для этого варианта использования это может выглядеть примерно так:

<!-- 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), потому что первый выше имеет более высокий приоритет (он имеет предикат). "Провал" соответствующий шаблон, второй, ловит все, что не является допустимым. Третий затем заботится о выводе categoryName значение в правильном направлении.

обратите внимание, что в этом сценарии нет необходимости специально соответствовать categories или category, потому что процессор будет автоматически обрабатывать все дочерние элементы, если мы не скажем ему иначе (в этом примере второй и третий шаблон не будут дополнительно обрабатывать дочерние элементы, потому что нет xsl:apply-templates в них).

этот подход более легко расширяется, чем императивный подход, потому что он автоматически имеет дело с несколькими категориями, и его можно расширить для других элементов или исключений, просто добавив другой соответствующий шаблон. Программирование без if-ветвей.

Примечание: нет такой вещи, как null в XML. Есть xsi: nil, но это редко используется, особенно редко в нетипизированных сценариях без какой-то схемы.

Если есть возможность, что элемент не существует в XML, я бы проверил, что элемент присутствует и что длина строки больше нуля:

<xsl:choose>
    <xsl:when test="categoryName and string-length(categoryName) &gt; 0">
        <xsl:value-of select="categoryName " />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="other" />
    </xsl:otherwise>
</xsl:choose>

Если узел не имеет значения, доступного во входном xml, как показано ниже xpath,

<node>
    <ErrorCode/>
</node>

функция string () преобразуется в пустое значение. Так что это прекрасно работает:

string(/Node/ErrorCode) =''

что-то вроде этого работает для меня:

<xsl:choose>
  <xsl:when test="string(number(categoryName)) = 'NaN'"> - </xsl:when> 
  <xsl:otherwise> 
    <xsl:number value="categoryName" />
  </xsl:otherwise>
</xsl:choose>

или наоборот:

<xsl:choose>
  <xsl:when test="string(number(categoryName)) != 'NaN'">
    <xsl:number value="categoryName" />
  </xsl:when> 
  <xsl:otherwise> - </xsl:otherwise>
</xsl:choose>

Примечание: Если вы не проверяете нулевые значения или не обрабатываете нулевые значения, IE7 возвращает -2147483648 вместо NaN.

как я могу проверить, является ли значение null или пустым с помощью XSL?

, если categoryName пусто?

это, вероятно, самое простое выражение XPath (тот, который в принятом ответе дает тест на противоположное, и будет дольше, если отрицается):

not(string(categoryName))

объяснение:

аргумент

по моему опыту, лучший способ-это:

<xsl:when test="not(string(categoryName))">
    <xsl:value-of select="other" />
</xsl:when>
<otherwise>
    <xsl:value-of select="categoryName" />
</otherwise>

используйте простой categoryName / text () такой тест отлично работает на <categoryName/> и <categoryName></categoryName>.

<xsl:choose>
    <xsl:when test="categoryName/text()">
        <xsl:value-of select="categoryName" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="other" />
    </xsl:otherwise>
</xsl:choose>

Я на самом деле нашел его лучше просто проверить длину строки, так как много раз поле не является нулевым, просто пустым

Comments

    Ничего не найдено.