Добавление запятой (,) или «или» в зависимости от положения между условным текстом с помощью XSLT - PullRequest
0 голосов
/ 24 апреля 2020

У меня 5 товаров. Ввод продукта P, QR, S, T XML будет отличаться через некоторое время, когда может появиться один, два, три, четыре или пять продуктов, но здесь 5 продуктов XML, опубликованные несколько раз, продукты могут повторяться как продукт Q два раза и продукт R три раза, и некоторые продукты могут пропустить

<products>
<product>Product_P</product>
<product>Product_Q</product>
<product>Product_R</product>
<product>Product_S</product>
<product>Product_T</product>
</products>

, если ввод xml 2 продукта повторяется:

<products>
    <product>Product_P</product>
    <product>Product_Q</product>
    <product>Product_R</product>
<product>Product_Q</product>
    <product>Product_R</product>
    <product>Product_S</product>
<product>Product_Q</product>
    <product>Product_R</product>
    <product>Product_T</product>
    </products>

, если на входе xml 3 отсутствуют некоторые продукты :

<products>
    <product>Product_P</product>
    <product>Product_Q</product>
    <product>Product_T</product>
    </products>

если ввод xml 4 других типа продукции:

<products>
    <product>Product_P</product>
    <product>Product_U</product>
    <product>Product_R</product>
<product>Product_V</product>
    <product>Product_R</product>
    <product>Product_W</product>
<product>Product_Q</product>
    <product>Product_W</product>
    <product>Product_T</product>
    </products>

Мне нужны продукты вывода, связанные с P, Q, R, S, T других продуктов нет Как уже упоминалось ниже:

если на входе есть один продукт, значение которого равно product = "Product_Q", я хочу просто напечатать

Product_Q

, если на входе есть значение двух продуктов, равное product = "Product_Q" и product = "Product_S", я хочу напечатать

Product_Q or Product_S

, если вход имеет значение трех продуктов, равное product = "Product_P", product = "Product_Q" и product = "Product_R", я хочу напечатать

Product_P, Product_Q or Product_R

, если вход имеет четыре значения продуктов, равные продукции t = "Product_P", product = "Product_Q", product = "Product_R" и product = "Product_T", я хочу напечатать

Product_P, Product_Q, Product_R, Product_S or Product_T

, если на входе есть пять значений продуктов, равных product = "Product_P" , product = "Product_Q", product = "Product_R", product = "Product_S" и product = "Product_T", я хочу напечатать

Product_P, Product_Q, Product_R, Product_S  or Product_T

Я пробовал приведенный ниже шаблон XSLT

<xsl:template match="products">
           <xsl:variable name="product" select="products/product"/>
                    <xsl:if test="$product='Product_P'">
                        <xsl:text>Product_P</xsl:text>
                    </xsl:if>
<xsl:if test="$product='Product_P' and Product_Q">
                        <xsl:text>or</xsl:text>
                    </xsl:if>
<xsl:if test="$product='Product_Q'">
                        <xsl:text>Product_Q</xsl:text>
                    </xsl:if>
<xsl:if test="$product='Product_P' and Product_Q and Product_R">
                        <xsl:text>or</xsl:text>
                    </xsl:if>
<xsl:if test="$product='Product_R'">
                        <xsl:text>Product_R</xsl:text>
                    </xsl:if>
<xsl:if test="$product='Product_S'">
                        <xsl:text>Product_S</xsl:text>
                    </xsl:if>
<xsl:if test="$product='Product_T'">
                        <xsl:text>Product_T</xsl:text>
                    </xsl:if>
    </xsl:template>

Пожалуйста, помогите спасибо заранее.

Ответы [ 2 ]

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

Первый шаг - определить отдельные продукты:

distinct-values(products/product)

, затем отфильтровать результат с помощью предиката, который выбирает продукты, которые вы хотите сохранить:

[matches(., '^Product_[PQRST]$')]

, затем добавить форматирование :

<xsl:for-each select="distinct-values(products/product)[matches(., '^Product_[PQRST]$')]">
  <xsl:value-of select="if (position()=1) then ''
                        else if (position()=last()) then ' or '
                        else ', '"/>
  <xsl:value-of select="."/>
</xsl:for-each>

Примечание: ваши требования по-прежнему ничего не говорят о требуемом порядке вывода.

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

Вы можете выполнить sh это с помощью рекурсивного шаблона:

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

  <xsl:template name="ListProducts">
    <xsl:param name="products" />

    <xsl:choose>
      <xsl:when test="count($products) = 1">
        <xsl:value-of select="$products"/>
      </xsl:when>
      <xsl:when test="count($products) = 2">
        <xsl:value-of select="concat($products[1], ' or ', $products[2])"/>
      </xsl:when>
      <xsl:otherwise>
        <!-- output first product and recursively call with remainder -->
        <xsl:value-of select="concat($products[1], ', ')"/>
        <xsl:call-template name="ListProducts">
          <xsl:with-param name="products" select="$products[position() > 1]" />
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="products">
    <xsl:copy>
      <xsl:call-template name="ListProducts">
        <xsl:with-param name="products" select="product" />
      </xsl:call-template>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Вывод при запуске на вашем образце XML:

<products>Product_P, Product_Q, Product_R, Product_S or Product_T</products>
...