Саксонский движок не создает файл с текстом - PullRequest
1 голос
/ 13 февраля 2020

Вчера я уже задавал вопрос о Saxon и XSLT , но до сих пор полностью не решил свою проблему. Коротко о том, чего я хочу достичь:

  1. В качестве первого входного файла у меня есть файл html со следующим кодом:

    `

              <h1>Use_Cases</h1>
              <table border="1">
                 <tr>
                    <td>file_name</td>
                    <td>function1()</td>
                    <td>function2()</td>
                    <td>function3()</td>
                    <td>function4()</td>
                    <td></td>
                 </tr>
                 <tr>
                    <td>test1</td>
                    <td>a+a;</td>
                    <td>b+b;</td>
                    <td>c+c;</td>
                    <td>d+d;</td>
                    <td></td>
                 </tr>
                 <tr>
                    <td>test2</td>
                    <td>a+a;</td>
                    <td>b+b;</td>
                    <td>c+c;</td>
                    <td>d+d;</td>
                    <td></td>
                 </tr>```
    

`

Моя цель - получить доступ к текстовым файлам с именами test1. cpp и test2. cpp, каждый из которых содержит 4 функции примерно так:

    function1(){
     a+a;}
     function2(){
     b+b;}
     function3(){
     c+c;}

Я написал такой код чтобы преобразовать мой html файл на основе последнего заданного вопроса:


    <xsl:template  match="/html/body/table" >
        <xsl:for-each select="/tr/td[1]">
            <xsl:variable name="file_name" select="../tr/td[1]"/>
                <xsl:result-document href="{$file_name}.cpp" method="text">
                    <xsl:apply-templates select="html/body/table/tr[1]/td[position() > 1 and position() &lt; 6]"/>    
                </xsl:result-document>
        </xsl:for-each>
    </xsl:template> 

      <xsl:template match="td">
          <xsl:param name="pos" select="position()"/>
          <xsl:value-of select="., '{', ../following-sibling::tr[1]/td[$pos + 1], '}'" separator="&#10;"/>
          <xsl:text>&#10;</xsl:text>
      </xsl:template>

Моя проблема в том, что Saxon не сообщает мне ни о какой ошибке или ошибке, она просто перестает работать и не создает никакого файла. Я также пытался обработать мой код в онлайн-среде IDE https://xsltfiddle.liberty-development.net/, но он говорит мне, что:

xsl: результат-документ отключен, когда функции расширения отключены

Какая у меня проблема? Почему Saxon перестает работать без создания какого-либо файла (и без ошибок)?

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 13 февраля 2020

Пара наблюдений:

(1)

 <xsl:template  match="/html/body/table" >
    <xsl:for-each select="/tr/td[1]">

Это явно неверно. «/ Tr / td» заставляет выбор быть из root документа, а не из текущего элемента. Для относительного выбора вы хотите `select =" tr / td [1] ".

Аналогично, когда вы делаете select="html/body....", вы делаете относительный выбор из неправильного контекста. Чтобы получить правильные выражения пути, важно понимать, как различные инструкции изменяют контекст.

(2) xsl: результат-документ отключен, когда функции расширения отключены

Это связано с тем, что xsltfiddle должен обрабатывать ненадежные таблицы стилей и не может позволить ненадежным таблицам стилей записывать документы в произвольные места в хранилище файлов сервера. Вы не получите эту проблему, если вы запустите (с настройками по умолчанию) на своем собственном сервере или ноутбуке.

(3) Саксон не сообщает мне ни о какой ошибке или ошибке, он просто прекращает работать и делает не создавать никаких файлов

Да, к сожалению, такой динамический язык c, как XSLT, приводит к тому, что неверное выражение пути не имеет никаких симптомов, кроме невозможности выбора чего-либо и, следовательно, неудачного выполнения часть вашего кода (например, тело xsl: for-each). XSLT с поддержкой схемы был разработан для решения этой проблемы, но он добавляет сложности, так что только небольшая часть пользователей фактически использует его - хотя по моему опыту, если вы сделаете предварительные усилия, он может дать хорошее вознаграждение за производительность, когда дело доходит до поддержание. При правильном использовании XSLT с учетом схемы есть большая вероятность, что неправильные выражения пути приведут к ошибке времени компиляции. Проблема в том, что люди, которые больше всего в этом нуждаются, являются новичками, а новичкам, естественно, не нужны дополнительные сложности.

1 голос
/ 13 февраля 2020

Ответ, который я отправил в ответ на ваш предыдущий вопрос: https://xsltfiddle.liberty-development.net/bwe3c5/1 и имеет код

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:strip-space elements="*"/>
  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:apply-templates select="html/body/table/tr[1]/td[position() > 1 and position() &lt; 6]"/>
  </xsl:template>

  <xsl:template match="td">
      <xsl:param name="pos" select="position()"/>
      <xsl:value-of select="., '{', ../following-sibling::tr[1]/td[$pos + 1], '}'" separator="&#10;"/>
      <xsl:text>&#10;</xsl:text>
  </xsl:template> 

</xsl:stylesheet>

Если вы запускаете Saxon из командной строки, вы можете просто использовать -o:file.text для определенного имени выходного файла; если вам нужно сделать это в коде XSLT, тогда используйте

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:strip-space elements="*"/>
  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:result-document href="file.text">
       <xsl:apply-templates select="html/body/table/tr[1]/td[position() > 1 and position() &lt; 6]"/>
    </xsl:result-document>
  </xsl:template>

  <xsl:template match="td">
      <xsl:param name="pos" select="position()"/>
      <xsl:value-of select="., '{', ../following-sibling::tr[1]/td[$pos + 1], '}'" separator="&#10;"/>
      <xsl:text>&#10;</xsl:text>
  </xsl:template> 

</xsl:stylesheet>

Что касается того, что Saxon не дает вам никаких ошибок, вы не сказали нам, как вы пытаетесь использовать его точно и какую версию точно.

Я думаю, что для вашего примера по какой-то причине вы переместили выделение <xsl:apply-templates select="html/body/table/tr[1]/td[position() > 1 and position() &lt; 6]"/>, которое я сделал в контексте match="/", в другой шаблон с другим шаблоном соответствия, а затем добавили for-each в В дальнейшем меняем контекст, просто я не ожидаю, что какой-либо документ HTML будет содержать другой в ячейке таблицы, поэтому относительный путь, начинающийся с html, когда ваш контекст - ячейка таблицы, вряд ли что-либо выберет.

Если в вашей таблице больше строк, и вы хотите отобразить каждую, но первую строку, в файл, то я думаю, что лучше обрабатывать эти строки в отдельном режиме, который создает файл результатов и изменяет логи c в другой шаблон для извлечения имен функций из первой строки:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:strip-space elements="*"/>
  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:apply-templates select="html/body/table/tr[position() > 1]" mode="file"/>
  </xsl:template>

  <xsl:template match="td">
      <xsl:param name="pos" select="position()"/>
      <xsl:value-of select="../../tr[1]/td[$pos + 1], '{', ., '}'" separator="&#10;"/>
      <xsl:text>&#10;</xsl:text>
  </xsl:template>

  <xsl:template match="tr" mode="file">
      <xsl:result-document href="{td[1]}.cpp">
          <xsl:apply-templates select="td[position() > 1 and position() &lt; 6]"/>
      </xsl:result-document>
  </xsl:template>

</xsl:stylesheet>

Что касается онлайн-скрипки, извините, но он не настроен на поддержку xsl:result-document, так как, с одной стороны, Saxon с настройки безопасности, необходимые на сервере publi c, отключают эту инструкцию, и, как с другой стороны, скрипка служит площадкой XSLT 1 - 3, в настоящее время не интеграция любых функций для создания и отображения более одного результата.

0 голосов
/ 13 февраля 2020

Спасибо за ваш ответ, я использую 9-ю версию Saxon. Для запуска saxon я использую файл .bat со следующим кодом:

@echo off
echo "Welcome to XMLT transformation...!!!"
set /p input1="Write name of XML (with '.xml' Extension) to transform=  "
echo %input1%
set /p input2="Write name of workbook-sheet (Excel Sheet name) to transform=    "
echo %input2%
java -jar C:\Users\saxon9he.jar %input1% transfer_xml.xsl workbook_name=%input2%
java -jar C:\Users\saxon9he.jar %input2%.html transfer_html.xsl 
pause

Сначала я создаю файл html из xml, а затем на основе этого файла html должен создать 2 текстовых файла. с кодом. Я уже попробовал ваш код, он работает, большое спасибо. Не могли бы вы объяснить, как я могу получить 2 файла с именами на /tr/td[1]?

...