XSLT: объединить список чисел с разделителем в соответствии с шаблоном

#xml #xslt

#xml #xslt

Вопрос:

Я не знаю, как решить мою основную проблему:

У меня есть <Polygon> элемент с @POINTS атрибутом, который содержит список чисел, например :

 <Polygon POINTS="337 363 330 221 443 221 472 203 497 225 512 373 494 370 475 392 417 373 385 381 348 421"/>
  

Я хотел бы выполнить преобразование XSL следующим образом:

 <zone type="Polygon" points="337,363 330,221 443,221 472,203 497,225 512,373 494,370 475,392 417,373 385,381 348,421"/>
  

Я хочу поставить запятую в соответствии с шаблоном, фактически точно между двумя числами.

Я пробовал с <xsl:for-each> и функцией concat (), это не работает.

заранее благодарю вас за совет и потраченное время

Комментарии:

1. Какой процессор XSLT, какую версию XSLT вы используете?

2. Если я не ошибаюсь, я использую XML-редактор Oxygen, который учитывает версии 1.0 и 2.0 XSLT, и я использую XSLT-процессор SAXON-PE 9.8.0.12

Ответ №1:

В XSLT 2/3 вы можете использовать

   <xsl:template match="@POINTS">
      <xsl:attribute name="points">
        <xsl:value-of separator=" ">
          <xsl:for-each-group select="tokenize(.)" group-adjacent="(position() - 1) idiv 2">
              <xsl:sequence select="string-join(current-group(), ',')"/>
          </xsl:for-each-group>
        </xsl:value-of>
      </xsl:attribute>
  </xsl:template>
  

Или в XSLT 3, который поддерживает Saxon 9.8 PE:

   <xsl:template match="@POINTS">
      <xsl:attribute name="points"
        select="let $tokens := tokenize(.)
                return 
                for-each-pair(
                  $tokens[position() mod 2 = 1], 
                  $tokens[position() mod 2 = 0], 
                  function($a, $b) { $a || ',' || $b }
                )"/>
  </xsl:template>
  

Комментарии:

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