XSLT - предыдущий счетчик значений и приращений - PullRequest
0 голосов
/ 30 января 2020

Я пытаюсь реализовать код php logi c в XSLT.

Структура xml выглядит как

Ввод:

<parent>
    <child>
        <id>1</id>
        <value>11</value>
    </child>
    <child>
        <id>2</id>
        <value>22</value>
    </child>
    <child>
        <id></id>
        <value>22</value>
    </child>
    <child>
        <id></id>
        <value>00</value>
    </child>
    <child>
        <id></id>
        <value>00</value>
    </child>
<parent>

Код sudo в php (logi c) I Я пытаюсь реализовать в XSLT следующее:

var Index = 1;
for each "child"{
    if( "id" is not empty ){
        Index += "id" + 1;
    }else{
        if( previous "value" == current "value" ){
            "id" = Index;
            Index++;
        }else{
            "id" = 1;
            Index = 2;
        }
    }
}

Как я понимаю, в XSLT у нас не может быть счетчика / переменной, которую мы можем обновлять на каждой итерации. Я считаю, что могу использовать preceding-sibling для сравнения предыдущего значения с текущим значением, но как рассчитать индекс в этой точке? Я могу использовать XSLT 2.0, если это облегчает / упрощает.

Есть идеи?

Вывод после преобразования должен выглядеть следующим образом:

Вывод:

<parent>
    <child>
        <id>1</id>
        <value>11</value>
    </child>
    <child>
        <id>2</id>
        <value>22</value>
    </child>
    <child>
        <id>6</id> <!-- "id" = "Index" calculated so far, since current value (22) = previous value (22) -->
        <value>22</value>
    </child>
    <child>
        <id>1</id> <!-- "id" = 1 since current value (00) != previous value (22) -->
        <value>00</value>
    </child>
    <child>
        <id>2</id> <!-- "id" = "Index" calculated so far, since currnet value (00) = previous value (00) --> 
        <value>00</value>
    </child>
<parent>

1 Ответ

1 голос
/ 30 января 2020

Вот попытка использования XSLT 3 и xsl:iterate:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="parent">
      <xsl:copy>
          <xsl:iterate select="child">
              <xsl:param name="index" select="1"/>
              <xsl:param name="previous-value" select="()"/>
              <xsl:variable name="value" select="value"/>
              <xsl:variable name="id" 
                select="(id[has-children()], if ($value = $previous-value) then $index else 1)[1]"/>
              <xsl:variable name="index"
                select="if (id[has-children()])
                        then $index + $id + 1
                        else if ($value = $previous-value)
                        then $index + 1
                        else 2"/>
              <xsl:apply-templates select=".">
                  <xsl:with-param name="id" select="$id" tunnel="yes"/>
              </xsl:apply-templates>
              <xsl:next-iteration>
                  <xsl:with-param name="index" select="$index"/>
                  <xsl:with-param name="previous-value" select="$value"/>
              </xsl:next-iteration>
          </xsl:iterate>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="id[not(has-children())]">
      <xsl:param name="id" tunnel="yes"/>
      <xsl:copy>{$id}</xsl:copy>
  </xsl:template>

</xsl:stylesheet>
...