XSLT: Как создать последовательность элементов, в которую каждый элемент входит условно? - PullRequest
0 голосов
/ 23 января 2020

Я хотел бы построить последовательность в XSLT 2, где каждый элемент последовательности индивидуально включен условно.

Что-то вроде этого (где выражения test на самом деле не так тривиальны):

<xsl:variable name="seq">
  <xsl:if test="true()">
    <xsl:value-of select="'foo'"/>
  </xsl:if>
  <xsl:if test="false()">
    <xsl:value-of select="'bar'"/>
  </xsl:if>
  <xsl:if test="true()">
    <xsl:value-of select="'baz'"/>
  </xsl:if>
</xsl:variable>

В этом случае я бы хотел, чтобы значение seq было последовательностью ('foo', 'baz').

Однако, мне кажется, что-то не хватает, потому что она работает не совсем так, как ожидалось , То, что мне возвращают для вышеупомянутого, является последовательностью с единственным элементом 'foobar' (то есть конкатенация строк того, что должно было быть всеми отдельными элементами). Если все условия ложные, я получаю последовательность с одним элементом, но этот элемент выглядит как пустая строка.

Примечание: не совсем понятно, что элемент <xsl:sequence> обязательно связан с построение новой последовательности и т. д. не имеет отношения к этому варианту использования. Кажется, это больше о ссылках на существующие элементы , а не копировании их.

Для контекста конкретного c варианта использования, который я сейчас пытаюсь решить: Я пытаюсь сгенерировать последовательность строк, представляющих классы HTML, каждая из которых включена в зависимости от другого логического выражения. Это приведет к списку переменной длины, между 0 и несколькими строками. Затем я планирую сериализовать этот список в строку, разделенную пробелами, как ожидает атрибут HTML class, например: string-join($classes, ' ').

Ответы [ 2 ]

0 голосов
/ 23 января 2020

Вместо этого вы можете использовать предикат для условной фильтрации:

<xsl:variable name="seq" as="xs:string*"
              select="('foo', 'bar', 'baz')[position() = (1, 3)]"/>

Здесь, например, будут выбраны первый и третий элементы последовательности, но смысл в том, чтобы использовать сжатую, выразительную силу XPath, а не XSLT-операторы для определения условия.

0 голосов
/ 23 января 2020

Экспериментируя с этим, я в конце концов нашел решение. Вам необходимо явно указать тип переменной, которая будет последовательностью строк! В частности, мне пришлось добавить атрибут as="xs:string*".

Получившийся XSLT становится:

<xsl:variable name="seq" as="xs:string*">
  <xsl:if test="true()">
    <xsl:value-of select="'foo'"/>
  </xsl:if>
  <xsl:if test="false()">
    <xsl:value-of select="'bar'"/>
  </xsl:if>
  <xsl:if test="true()">
    <xsl:value-of select="'baz'"/>
  </xsl:if>
</xsl:variable>

При этом все заработало как положено! Я получил последовательность ('foo', 'baz') в случае выше. При изменении всех условий на false() я получил последовательность с нулевыми элементами.

...