XSLT — Использование copy-of, похоже, игнорирует формулировку «if» в шаблоне

#xml #xslt

#xml #xslt

Вопрос:

Ранее сегодня я опубликовал другой запрос относительно включения тегов, которые применяются к разным шаблонам, и я получил несколько ответов, которые помогли мне получить желаемый результат. Теперь мне нужно решить еще одну маленькую деталь. Мой XML выглядит следующим образом:

 <?xml version="1.0" encoding="ISO-8859-1"?>
<root>
    <account>
        <name>accountA</name>
    </account>
    <period>
        <type>priormonth</type>
        <balance>0.0000</balance>
    </period>
    <period>
        <type>currentmonth</type>
        <balance>20.0000</balance>
    </period>
    <account>
        <name>accountB</name>
    </account>
    <period>
        <type>priormonth</type>
        <balance>30.0000</balance>
    </period>
    <period>
        <type>currentmonth</type>
        <balance>0.0000</balance>
    </period>
</root>
  

Мой XSLT выглядит следующим образом:

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

<xsl:template match="/root">
        <xsl:apply-templates select="account"/>
</xsl:template>

<xsl:template match="account">
    <xsl:copy>
        <xsl:copy-of select="name" />
        <perioddata>
            <xsl:copy-of select="following-sibling::period[position()amp;<=2]" />
        </perioddata>
    </xsl:copy>
</xsl:template>

<xsl:template match="period">
    <period>
    <type> <xsl:value-of select="type"/> </type>
    <balance>
    <xsl:if test="balance != 0">
        <xsl:value-of select="balance"/>
    </xsl:if>
    </balance>
    </period>
</xsl:template>

</xsl:stylesheet>
  

Это приводит к следующему результату:

 <account>
  <name>accountA</name>
  <perioddata>
      <period>
          <type>priormonth</type>
          <balance>0.0000</balance>
      </period>
      <period>
          <type>currentmonth</type>
          <balance>20.0000</balance>
      </period>
   </perioddata>
</account>
<account>
  <name>accountB</name>
  <perioddata>
      <period>
          <type>priormonth</type>
          <balance>30.0000</balance>
      </period>
      <period>
          <type>currentmonth</type>
          <balance>0.0000</balance>
      </period>
   </perioddata>
</account>
  

Этот вывод прекрасен, за исключением того, что я хочу, чтобы мои строки с:

 <balance>0.0000</balance>
  

чтобы отображаться как:

 <balance/>
  

Приносим извинения за любые опечатки выше…В основном я просто печатал, а не вырезал / вставлял. Я читал, что «copy-of» может совпадать с «value-of» и выдавать текстовый вывод, который мог бы объяснить, почему предложение «if» не распознает нулевое значение. Я пытался сделать:

 <xsl:if test="number(balance) != 0">
  

но все еще не получил желаемых результатов. Спасибо.

Ответ №1:

Попробуйте изменить

 <xsl:copy-of select="following-sibling::period[position()amp;<=2]" />
  

Для

 <xsl:apply-templates select="following-sibling::period[position()amp;<=2]" />
  

Ваш шаблон «period» не используется, поскольку узлы используются шаблоном «root».

Комментарии:

1. Фантастика! Это сработало… Спасибо. Не знаю, почему я не попробовал это раньше, потому что я поиграл с различными параметрами apply-templates. Вы сделали мою пятницу!

2. Я внес незначительные изменения в свой ответ. На самом деле это «корневой» шаблон, который использует узлы «period» в качестве побочного эффекта, поскольку вы ничего не делали с ними в «корневом» шаблоне. Вот почему вы должны использовать apply-templates вместо copy-of. Ваша copy-of просто копировала узлы дословно, не вызывая ваш шаблон.