Перерыв для каждого цикла в xslt

Я должен выйти из цикла for-each, если @PercentOfAmountActive не равно 0 или 100.

Это мой XML:

<SamplePointSet Id="1" StartDate="2012-01-01T04:00:00Z" CalendarId="1" Cyclic="6" ForAttribute="0" ObjectId="0" ProbabilityFunctionId="0" TableNumber="0" TimePeriodId="4" ParentId="1">
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="100" Sequence="1" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="0" Sequence="2" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="100" Sequence="3" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="0" Sequence="4" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="100" Sequence="5" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="0" Sequence="6" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="100" Sequence="7" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="0" Sequence="8" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="100" Sequence="9" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="0" Sequence="10" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="100" Sequence="11" SamplePointSetId="1" />
    <SamplePoint NumberOfActiveTimePeriods="30" PercentOfAmountActive="0" Sequence="12" SamplePointSetId="1" />
  </SamplePointSet>

Ниже приведен xslt-код

<xsl:for-each select=".../CM:SamplePointSet/CM:SamplePoint">
  <xsl:variable name="varActiveTimePeriod" select="./@NumberOfActiveTimePeriods * $varMultiple"/>
  <xsl:variable name="varPercentOfAmountActive" select="./@PercentOfAmountActive"/>

  <!-- . . . some Condition To break if (percent of amount active) not 0 or 100 -->

  <xsl:value-of select="CMXsltExtObject:SetRecurenceRule($varActiveTimePeriod, $varPercentOfAmountActive, $varCalendarFrequency)"/>
</xsl:for-each>

Есть ли способ сделать это?


person Hussey    schedule 29.06.2012    source источник


Ответы (2)


Избегайте циклов for-each в XSLT. Вместо этого, по возможности, применяйте свои узлы к шаблонам, используя XPath для выбора только тех узлов, которые подходят.

Вы можете добиться эффекта разрыва, применяя шаблоны только к этим узлам...

  • чей атрибут @PercentOfAmountActive равен 0 или 100
  • ни у одного из предыдущих братьев и сестер нет атрибута @PercentOfAmountActive, который не равен 0 или 100.

Вот упрощенный пример, который вы можете запустить на этой XMLPlayground.

XML

<root>
    <node attr='0'>hello 1</node>
    <node attr='100'>hello 2</node>
    <node attr='0'>hello 3</node>
    <node attr='100'>hello 4</node>
    <node attr='1'>hello 5</node>
    <node attr='0'>hello 6</node>
    <node attr='100'>hello 7</node>
</root>

XSLT

<xsl:template match='/'>
    <ul>
        <xsl:apply-templates select='root/node[(@attr = 0 or @attr = 100) and not(preceding-sibling::*[@attr != 0 and @attr != 100])]' />
    </ul>
</xsl:template>

<xsl:template match='node'>
    <li><xsl:value-of select='.' /></li>
</xsl:template>

Выводятся только первые четыре узла, имитируя эффект «разрыва» при попадании в неподходящий узел.

person Mitya    schedule 29.06.2012

Инструкция xsl:for-each — это не цикл, а сопоставление входной последовательности с выходной последовательностью. То, что вы описываете в процедурных терминах как «разрыв» из «цикла», на самом деле говорит о том, что вы хотите, чтобы сопоставление выбирало только те элементы во входной последовательности перед первым, значение атрибута которого не равно 1 или 100.

Наиболее эффективным решением, вероятно, является использование родственной рекурсии:

<xsl:template match="SamplePointSet">
    <xsl:apply-templates select="SamplePoint[1]"/>
</xsl:template>

<xsl:template match="SamplePoint">
  ... some processing ...
  <xsl:if test="@A = 1 or @A = 100">
    <xsl:apply-templates select="following-sibling::SamplePoint[1]"/>
  </xsl:if>
</xsl:template>
person Michael Kay    schedule 29.06.2012
comment
Я хочу, чтобы, если приходит любое значение, отличное от 0 или 100, выйти из этого для каждого и не обрабатывать дальше... - person Hussey; 30.06.2012