WedX - журнал о программировании и компьютерных науках

Неожиданное поведение xsl: apply-templates / xsl: with-param с Xalan-J и saxon по сравнению с xsltproc

Я изо всех сил пытаюсь научиться использовать XSLT 1.0 из java-кода, но постепенно постепенно теряю рассудок.

У меня есть Xalan-J (как xalan.jar, так и xsltc.jar со всеми банками зависимостей), saxon и jing (последние два используются в другом месте в моем проекте) в моем пути к классам, и я использую JAXP с комбинацией вызовов System.setProperty для принудительно использовать реализации классов, такие как TransformerFactory, как я хочу. Это также позволяет мне видеть, как разные процессоры XSLT ведут себя с использованием одного файла преобразования XSL, просто изменяя свойства из кода. Кроме того, я также использую xsltproc из среды cygwin, чтобы посмотреть, что он делает. Я также отлаживаю в Oxygen, чтобы убедиться, что мой Java-код не является проблемой.

Взгляните на этот фиктивный XSL:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="https://www.w3.org/1999/XSL/Transform"                
                xmlns:rng="https://relaxng.org/ns/structure/1.0"
                xmlns:ex="https://example.com/ns/ex"
                version="1.0">

  <xsl:output method="xml" encoding="utf-8"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
    <!-- Start by finding the root grammar element -->
    <xsl:apply-templates select="rng:grammar"/>
  </xsl:template>

  <xsl:template match="/rng:grammar">
    <!-- Continue with child grammar elements -->
    <xsl:apply-templates select="descendant::rng:grammar"/>
  </xsl:template>

  <xsl:template match="rng:grammar">
    <!-- set the variable and pass it's value to another template -->
    <xsl:variable name="parameter" select="'any-string-value'"/>
    <xsl:message>initial value: <xsl:value-of select="$parameter"/></xsl:message>
    <xsl:apply-templates select="descendant::ex:data">
      <xsl:with-param name="parameter" select="$parameter"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="rng:optional">
    <!-- use the param value here -->
    <xsl:param name="parameter"/>
    <xsl:message>final value: <xsl:value-of select="$parameter"/></xsl:message>
  </xsl:template>

</xsl:stylesheet>

Он ничего не делает, кроме вызова некоторых шаблонов, которые работают с этим фиктивным документом экземпляра XML:

<?xml version="1.0" encoding="UTF-8"?>
<grammar
   xmlns="https://relaxng.org/ns/structure/1.0"
   xmlns:ex="https://example.com/ns/ex"
   datatypeLibrary="https://www.w3.org/2001/XMLSchema-datatypes">
  <start>
    <grammar ex:subgram="something" ns="https://example.com/ns/something">
      <start>
        <ex:data>
          <optional />
        </ex:data>
      </start>
    </grammar>
  </start>
</grammar>

Я не знаю, что делаю неправильно, но передача значения единственной переменной в этом XSL работает только с xsltc и xsltproc. И нормальный ксалан, и саксон не могут передать значение. См. Результаты ниже.

xsltproc:

$ xsltproc transformation.xsl instance.xml
initial value: any-string-value
final value: any-string-value

Скомпилированный процессор Xalan (xsltc, а также с реализацией по умолчанию java 1.6):

Implementation: org.apache.xalan.xsltc.trax.TransformerFactoryImpl loaded from: ./lib/xalan-j_2_7_1/xsltc.jar
initial value: any-string-value
final value: any-string-value

Интерпретирующий процессор Xalan (xalan):

Implementation: org.apache.xalan.processor.TransformerFactoryImpl loaded from: ./lib/xalan-j_2_7_1/xalan.jar
initial value: any-string-value
final value:

саксон:

Implementation: com.icl.saxon.TransformerFactoryImpl loaded from: ./lib/saxon6-5-5/saxon.jar
initial value: any-string-value
final value:

Мне это нужно для работы с xalan (причина - приемлемая поддержка EXSLT). Понятия не имею, в чем может быть причина разных результатов. Я пытался, что все эти процессоры реализуют XSLT 1.0, но думаю, что они делают это по-разному. То, что я пытаюсь сделать в своем XSL, несовместимо с XSLT 1.0? Есть ли обходной путь, который я мог бы использовать, чтобы заставить это работать?


Ответы:


1

Объяснение простое:

  <xsl:template match="rng:optional">
    <!-- use the param value here -->
    <xsl:param name="parameter"/>
    <xsl:message>final value: <xsl:value-of select="$parameter"/></xsl:message>
  </xsl:template>

rng:optional является дочерним по отношению к ex:data.

В ex:data нет сопоставления с шаблоном, поэтому он обрабатывается встроенным шаблоном XSLT для узла элемента.

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

Таким образом, шаблон, соответствующий rng:optional (см. Выше), выбирается для выполнения встроенным шаблоном XSLT для элементов, и этому выбранному шаблону не передаются никакие параметры.

Следовательно, значение параметра parameter - это пустая строка, и вы получите правильный вывод как от Saxon, так и от XalanJ.

09.02.2012
  • Это действительно имеет смысл. Кажется, что встроенные шаблоны xsltproc и xsltc обрабатывают параметры, даже если они не должны ... превращать то, что вы считаете переносимым XSL, в полную противоположность. 09.02.2012
  • @predi: Итак, решение состоит в том, чтобы иметь шаблон, соответствующий ex:data, в котором объявлен параметр и который будет передавать его через свой xsl:apply-templates 09.02.2012
  • да. Если вы добавите отсутствующий шаблон, параметр будет иметь ожидаемое значение (в этом шаблоне). Затем он должен быть должным образом делегирован на всем пути между вашей начальной точкой и вашей целью, даже если промежуточная часть вам бесполезна. Срезание углов с помощью нисходящей оси или чего-то в этом роде недопустимо, если используются параметры. 09.02.2012
  • В XSLT 2.0 и 2.0 + можно использовать функцию, называемую параметрами туннеля. 09.02.2012
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]