Печать разделенных запятыми токенов, когда они были найдены в другом узле - PullRequest
0 голосов
/ 02 марта 2019

В этом примере показан довольно стандартный способ использования for-each для циклического перебора данных и вывода каждого значения через запятую.Первому элементу не предшествует запятая при использовании функции position().

ВХОД:

<file><data>
    <item>Anton</item>
    <item>Bruce</item>
    <item>Chris</item>
</data></file>

ТРАНСФОРМАЦИЯ:

<xsl:template match="/">
    <xsl:apply-templates select="/file/data" />
</xsl:template>

<xsl:template match="/file/data">
    <xsl:for-each select="item">
        <xsl:if test="position()&gt;1">
            <xsl:value-of select="', '" />
        </xsl:if>
        <xsl:value-of select="." />
    </xsl:for-each>
</xsl:template>

РЕЗУЛЬТАТ:

Anton, Bruce, Chris

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

INPUT:

<file>
    <data>
        <item>2</item>
        <item>4</item>
        <item>6</item>
    </data>

    <names>
        <person><id>1</id><name>Anton</name></person>
        <person><id>2</id><name>Bruce</name></person>
        <person><id>3</id><name>Chris</name></person>
        <person><id>4</id><name>Dirk</name></person>
        <person><id>5</id><name>Erik</name></person>
        <person><id>6</id><name>Fred</name></person>
    </names>
</file>

ПРЕОБРАЗОВАНИЕ:

<xsl:template match="/">
    <xsl:apply-templates select="/file/data" />
</xsl:template>

<xsl:template match="/file/data">
    <xsl:for-each select="item">
        <xsl:call-template name="getNames">
            <xsl:with-param name="soughtid">
                <xsl:value-of select="." />
            </xsl:with-param>
        </xsl:call-template>
    </xsl:for-each>
</xsl:template>

<xsl:template name="getNames">
    <xsl:param name="soughtid" />

    <xsl:for-each select="/file/names/person">
        <xsl:variable name="currentid">
            <xsl:value-of select="id"/>
        </xsl:variable>
        <xsl:if test="$currentid=$soughtid">
            <xsl:if test="position()&gt;1">         <!-- problematic -->
                <xsl:value-of select="', '"/>
            </xsl:if>
            <xsl:value-of select="name"/>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

РЕЗУЛЬТАТ:

, Bruce, Dirk, Fred

На этот раз результат начинается с запятой.Это имеет смысл, потому что теперь position () ссылается на итератор над узлом <names>.Первый элемент для печати - это второй <person> в узле <names>.

Как исправить этот код, чтобы результат никогда не начинался с запятой?Я использую XSLT v1.0

1 Ответ

0 голосов
/ 02 марта 2019

Вы можете убедиться, что обрабатываете только те элементы, которые вас интересуют, переместив сравнение в предикат, например <xsl:for-each select="/file/names/person[id = $soughtid]">.

Я бы реструктурировал весь код для использования ключа:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="text"/>

  <xsl:key name="pers-by-id" match="names/person" use="id"/>

  <xsl:template match="/">
      <xsl:apply-templates select="key('pers-by-id', file/data/item)/name"/>
  </xsl:template>

  <xsl:template match="name">
      <xsl:if test="position() > 1">, </xsl:if>
      <xsl:value-of select="."/>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / ej9EGc4

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...