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

В документе XML у меня есть некоторые адресные данные..

<zip>08001</zip>
<zipPlus xsi:nil="true" />

а также

<zip>08002</zip>
<zipPlus>4512</zipPlus>

Вкл хочу показывать значение zip plus только в том случае, если есть значение для использования. (для целей этого примера мне все равно, правильный ли это формат zip plus)

Попытка использовать следующий фрагмент в XSLT, кажется, никогда не работает, и я думаю, что это связано с тем, как я проверяю значение xsl:nil

<EmployerZipCode>
      <xsl:value-of select="zip"/>
      <xsl:if test="zipPlus != @xsl:nil">
        <xsl:value-of select="'-'"/>
        <xsl:value-of select="zipPlus"/>
      </xsl:if>
      <xsl:value-of select="$sepChar"/> <!--this is a comma -->
</EmployerZipCode>

Результаты, которые я получаю, всегда

08001,
08002,

не

08001,
08002-4512,

Как правильно проверять нулевые светодиодные элементы в XSLT? Есть ли другие способы обойти эту проблему и получить желаемый результат?

5 ответов

Решение

После еще одного тестирования ни один из ответов, включающих проверку атрибута nil, не работает надежно.

Мне пришлось прибегнуть к использованию string-length(), чтобы получить нужный мне результат.

<EmployerZipCode>
  <xsl:value-of select="zip"/>
  <xsl:if test="string-length(zipPlus) &gt; 0">
    <xsl:value-of select="'-'"/>
    <xsl:value-of select="zipPlus"/>
  </xsl:if>
  <xsl:value-of select="$sepChar"/>
</EmployerZipCode>
<xsl:if test="not(zipPlus/@xsi:nil='true')">

В XSLT 2.0, по причинам, которые я никогда полностью не понимал, есть пользовательская функция

test="not(nilled(zipPlus))"

Очень странно, что ты не заставил его работать. Возможно, вам не хватает декларации пространства имен или изменения префикса xsi в xsl это невидимая опечатка в вашем преобразовании. Проверь лучше. Вот мой тест:

XSLT 1.0 с саксонской 6.5

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xsi="test">
    <xsl:output method="text" indent="yes"/>

    <xsl:template match="EmployerZipCode">
        <EmployerZipCode>
            <xsl:value-of select="zip"/>
            <xsl:if test="not(zipPlus/@xsi:nil)">
                <xsl:value-of select="'-'"/>
                <xsl:value-of select="zipPlus"/>
            </xsl:if>
            <xsl:value-of select="','"/> <!--this is a comma -->
        </EmployerZipCode>
    </xsl:template>
</xsl:stylesheet>

Учитывая вход:

<?xml version="1.0" encoding="utf-8"?>
<test xmlns:xsi="test">
    <EmployerZipCode>
        <zip>08001</zip>
        <zipPlus xsi:nil="true" />
    </EmployerZipCode>
    <EmployerZipCode>
        <zip>08002</zip>
        <zipPlus>4512</zipPlus>
    </EmployerZipCode>
</test>

Производит:

08001,
08002-4512,

Меня устраивает

Исходный XML:

            <zipPlus xsi:nil="true"/>
                      or
            <zipPlus>123456</zipPlus>

XSLT:

            <xsl:if test="not(zipPlus/@xsl:nil='true')">
                <xsl:value-of select="zipPlus"/>
            </xsl:if>

Результат XML

            <zipPlus/>
            or
            <zipPlus>123456</zipPlus>
Другие вопросы по тегам