XSLT 1.0 Как обновить или вставить элемент после необязательного элемента - PullRequest
1 голос
/ 25 апреля 2020

Это похоже на вопрос: XSLT-1.0: Как вставить элемент в определенную c позицию по отношению к родительскому элементу , но ответ там не распространяется на случай, когда tag3 отсутствует во входных данных XML

Я хочу вставить или обновить тег (скажем, tag4) в документе XML, который выглядит следующим образом, за исключением того, что tag1, tag2, tag3, tag4 и tag5 являются необязательными.

<Begin>
    <tag1 value="a" />
    <tag2 value="b" />
    <tag3 value="c" />
    <tag4 value="d" />
    <tag5 value="e" />
</Begin>

Т.е. ниже приведены примеры входов и выходов

Вход:

<Begin>
</Begin>

Выход:

<Begin>
    <tag4 value="updated" />
</Begin>

Вход:

<Begin>
    <tag4 value="d" />
</Begin>

Выход:

<Begin>
    <tag4 value="updated" />
</Begin>

Вход:

<Begin>
    <tag1 value="a" />
    <tag5 value="e" />
</Begin>

Выход:

<Begin>
    <tag1 value="a" />
    <tag4 value="updated" />
    <tag5 value="e" />
</Begin>

Вход:

<Begin>
    <tag1 value="a" />
    <tag2 value="b" />
    <tag5 value="e" />
</Begin>

Выход:

<Begin>
    <tag1 value="a" />
    <tag2 value="b" />
    <tag4 value="updated" />
    <tag5 value="e" />
</Begin>

Вход:

<Begin>
    <tag1 value="a" />
    <tag2 value="b" />
    <tag3 value="c" />
    <tag5 value="e" />
</Begin>

Выход:

<Begin>
    <tag1 value="a" />
    <tag2 value="b" />
    <tag3 value="c" />
    <tag4 value="updated" />
    <tag5 value="e" />
</Begin>

ОБНОВЛЕНИЕ

Я также хочу иметь возможность сохранить любые атрибуты, которые могут уже присутствовать в элементе Begin или tag4, например:

Ввод:

<Begin someAttribute="someValue">
    <tag1 value="a" />
    <tag2 value="b" />
    <tag3 value="c" />
    <tag4 value="d" someOtherAttribute="someOtherValue" />
    <tag5 value="e" />
</Begin>

Вывод:

<Begin someAttribute="someValue">
    <tag1 value="a" />
    <tag2 value="b" />
    <tag3 value="c" />
    <tag4 value="updated" someOtherAttribute="someOtherValue" />
    <tag5 value="e" />
</Begin>

Ответы [ 2 ]

1 голос
/ 25 апреля 2020

Попробуйте:

<xsl:template match="Begin">
  <Begin>
    <xsl:copy-of select="tag1 | tag2 | tag3"/>
    <tag4 value="updated"/>
    <xsl:copy-of select="tag5"/>
  </Begin>
</xsl:template>
0 голосов
/ 26 апреля 2020

Дайте этому попытку ... Проследите это в отладчике, чтобы помочь вам разобраться, если это необходимо.

    <xsl:template match="Begin">
      <xsl:copy>
        <!-- Apply any attributes for Begin.  -->
        <xsl:apply-templates select="@*"/>

        <!-- Output the tag* nodes before tag4. -->
        <xsl:apply-templates select="tag1|tag2|tag3"/>

        <xsl:choose>
          <!-- Is there already a tag4? -->
          <xsl:when test="tag4">
            <xsl:apply-templates select="tag4"/>
          </xsl:when>
          <xsl:otherwise>
            <!-- Create tag4 -->
            <tag4 value="updated"/>
          </xsl:otherwise>
        </xsl:choose>

        <!-- Output the tag* nodes after tag4. -->
        <xsl:apply-templates select="tag5"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="tag4">
      <xsl:copy>
        <xsl:attribute name="value">d</xsl:attribute>
        <xsl:attribute name="someOtherAttribute">someOtherValue</xsl:attribute>
        <xsl:apply-templates select="node()"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="node()|@*">
      <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>
...