Выберите значения xsl:variable его дочерних узлов

У меня есть файл .ods, и я хочу получить доступ к значениям table-cells в table-rows по значению первого столбца для данной строки. Так что их направление в моем случае.

Итак, расчетная таблица выглядит так:

First_Name | Last_Name
Peter      | Parker
Emma       | Stone
...

Вот мой файл xslt-export-filter:

SuperBasicExportFilter.xslt

<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:stylesheet
  version = "1.0"
  xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
  xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
  xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
  xmlns:table = "urn:oasis:names:tc:opendocument:xmlns:table:1.0"
  xmlns:text = "urn:oasis:names:tc:opendocument:xmlns:text:1.0"
  xmlns:office = "urn:oasis:names:tc:opendocument:xmlns:office:1.0"
  exclude-result-prefixes = "table text office"
>

  <xsl:output
    method = "xml"
    indent = "yes"
    encoding = "UTF-8"
    omit-xml-declaration = "no"
  />

  <xsl:template match = "/">

    <xsl:variable name = "columnHeadings">
      <xsl:for-each select = "//table:table/table:table-row[not(preceding::table:table-row)]//table:table-cell">
        <xsl:element name = "heading">
          <xsl:attribute name = "name" select = "text:p" />
          <xsl:value-of select = "position()" />
        </xsl:element>
      </xsl:for-each>
    </xsl:variable>

    <html>
      <body>

      <h1>Hello</h1>
      <xsl:message>columnHeadings: <xsl:value-of select = "$columnHeadings" /></xsl:message>

      <table>
        <xsl:for-each select = "//table:table/table:table-row">

          <xsl:if test = "position() > 1">

            <tr>
              <td>
                First Column Value
                <xsl:value-of select = "table:table-cell[1]/text:p" />
                <!-- <xsl:value-of select = "table:table-cell[$columnHeadings/heading[@name='First_Name']]/text:p" /> -->
              </td>
              <td>
                Second Column Value
                <xsl:value-of select = "table:table-cell[2]/text:p" />
                <!-- <xsl:value-of select = "table:table-cell[$columnHeadings/heading[@name='Last_Name']]/text:p" /> -->
              </td>
            </tr>

          </xsl:if>

        </xsl:for-each>
      </table>
      </body>
    </html>

  </xsl:template>

</xsl:stylesheet>

Сообщение показывает "columnHeadings: 1234567891011121314" и так далее. Таким образом, он правильно устанавливает значения позиции.

Я попытался получить значения на основе атрибута «имя» в элементе «заголовок». Но я никак не могу получить значения по отдельности. Кажется, я не могу использовать $columnHeadings с любым выражением XPath. Он просто возвращает «Оценка Xpath не дала результата».

Я пытался

  • обертывание элементов «заголовок» элементом «columnHeadings» внутри переменной и установка значения «как» переменной в «элемент ()»
  • используя функцию "node-set" (после импорта "exslt" ns)
  • используя <xsl:variable name = "columnHeadingsNode" select = "document('')//xsl:variable[@name = 'columnHeadings']" />, чтобы затем получить значение
  • используя элемент xsl:key, например <xsl:key name = "columnHeadings" match = "//table:table/table:table-row[not(preceding::table:table-row)]//table:table-cell" use = "text:p" /> , но таким образом я не могу получить к нему доступ на основе «имени»

Какие еще вещи я могу попытаться получить доступ к содержимому переменной с выражением xpath?

Можно ли вообще получить доступ к таким значениям, как table:table-cell[$columnHeadings/heading[@name='Last_Name']]?


Ответы на комментарии:

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

Я использую то, что использует libreoffice 7.4.5.1. Могу ли я это изменить? xsl:vendor — «libxslt», а версия — «1.0» в соответствии со значениями <xsl:value-of select = "system-property('xsl:vendor')"/> и xsl:version.

Вы получаете сообщение об ошибке <xsl:attribute name = "name" select = "text:p" />?

Я на самом деле нет, почему-то. Тест проходит без ошибок. Я получаю новую вкладку браузера с созданным выводом xml и без ошибок.

Я попытался поставить галочку «Фильтру требуется процессор XSLT 2.0», но тогда я больше не могу тестировать фильтр и не получаю никаких результатов.

Какова общая цель этого упражнения?

Я хочу иметь возможность выбирать значения в столбцах по соответствующему заголовку столбца, а не по индексу, потому что я хочу сделать его максимально переносимым. По крайней мере, я думаю, что это помогло бы достичь этой цели. У меня 184 столбца. Я полагаю, что имена столбцов не изменятся с такой вероятностью, как индекс столбца.

С процессором XSLT 1.0 ваша переменная представляет собой фрагмент дерева результатов (RTF), либо переключитесь на процессор XSLT 2 или 3 (например, Saxon HE (последняя стабильная версия 11.5)) или узнайте, какой процессор XSLT 1.0 вы используете и какой тип Функция расширения, такая как exsl:node-set, поддерживает преобразование фрагмента результирующего дерева в набор узлов.

Martin Honnen 19.02.2023 09:57

Вы получаете сообщение об ошибке <xsl:attribute name = "name" select = "text:p" />? Любой процессор XSLT 1.0 с version = "1.0" должен выдавать ошибку, поскольку XSLT 1.0 не разрешает атрибут select для xsl:attribute.

Martin Honnen 19.02.2023 10:58

Вы можете посмотреть на stackoverflow.com/q/75514330/3016153. Обратите внимание, что процессор libxslt поддерживает ряд функций расширения, в том числе str:tokenize().

michael.hor257k 20.02.2023 22:38
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Ускорьте разработку веб-приложений Laravel с помощью этих бесплатных стартовых наборов
Laravel - это мощный PHP-фреймворк, используемый для создания масштабируемых и надежных веб-приложений. Одним из преимуществ Laravel является его...
Что такое двойные вопросительные знаки (??) в JavaScript?
Что такое двойные вопросительные знаки (??) в JavaScript?
Как безопасно обрабатывать неопределенные и нулевые значения в коде с помощью Nullish Coalescing
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание ресурсов API Laravel: Советы по производительности и масштабируемости
Создание API-ресурса Laravel может быть непростой задачей. Она требует глубокого понимания возможностей Laravel и лучших практик, чтобы обеспечить...
Как сделать компонент справочного центра с помощью TailwindCSS
Как сделать компонент справочного центра с помощью TailwindCSS
Справочный центр - это веб-сайт, где клиенты могут найти ответы на свои вопросы и решения своих проблем. Созданный для решения многих распространенных...
Асинхронная передача данных с помощью sendBeacon в JavaScript
Асинхронная передача данных с помощью sendBeacon в JavaScript
В современных веб-приложениях отправка данных из JavaScript на стороне клиента на сервер является распространенной задачей. Одним из популярных...
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Как подобрать выигрышные акции с помощью анализа и визуализации на Python
Отказ от ответственности: Эта статья предназначена только для демонстрации и не должна использоваться в качестве инвестиционного совета.
0
3
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Намерение <xsl:attribute name = "name" select = "text:p" /> не может создать атрибут со значением в XSLT 1; это должно вызвать ошибку, но кажется, что ваш XSLT-процессор игнорирует select.

Поэтому постарайтесь

<xsl:attribute name = "name">
   <xsl:value-of select = "text:p"/>
</xsl:attribute>

Вместо.

Таким образом, я бы подумал, что, например. <xsl:variable name = "columnHeadings-ns" select = "exsl:node-set($columnHeadings)" xmlns:exsl = "http://exslt.org/common"/> должен позволить вам использовать, например. <xsl:value-of select = "table:table-cell[$columnHeadings-ns/heading[@name='First_Name']]/text:p"/>.

Мне пришлось обернуть индекс из $columnHeadings в вызов number вот так <xsl:value-of select = "table:table-cell[number($columnHeadings-ns/heading[@‌​name='First_Name'])]‌​/text:p"/>. Я предполагаю, что функция node-set преобразовала его в строку.

dweipert 20.02.2023 10:26

Другие вопросы по теме