XSLT fop-0.95: проблема с dyn: оценить - PullRequest
0 голосов
/ 05 октября 2009

Я боролся со странным поведением fop 0.95 (не знаю, делаю ли я что-то не так, или если есть обходной путь).

У меня есть автоматически сгенерированный XML следующим образом:

<projectteam>
 <projectname>Report Generation</projectname>
 <RoleTypes>
         <dev/>
         <qa/>
         <doc/>
 </RoleTypes>
 <member>
   <name>John</name>
   <dev>200</dev>
 </member>
 <member>
   <name>Max</name>
   <dev>60</dev>
 </member>
 <member>
   <name>Henry</name>
   <qa>80</qa>
 </member>
 <member>
   <name>Peter</name>
   <qa>40</qa>
 </member>
</projectteam>

(Примечание: это смоделированный пример, но у меня очень похожая потребность там, где мне нужно создавать отчеты по окончании работы с несколькими столбцами, похожими на roleTypes)

Моя цель - отобразить вышеуказанные данные в формате PDF следующим образом:

Name   | dev | qa  | doc |
--------------------------
John   | 100 |     |     |
Max    |  60 |     |     |
Henry  |     |  80 |     |
Peter  |     |  40 |     |

Я использовал xsl: for-each для циклического перебора элементов RoleTypes / * для определения столбцов таблицы, и затем динамически построенное выражение XPath (используя dyn: Оценка exslt), чтобы получить данные для ячеек, соответствующих ролям (dev, qa и doc).

Моя таблица стилей xsl работает должным образом, если я запускаю ее через препроцессор (xsltproc) чтобы сгенерировать .fo, а затем использовать fop для преобразования этого .fo в pdf. Но когда я использую fop напрямую (то есть один шаг: fop -xml blah.xml -xsl blah.xsl -pdf out.pdf), я получаю странные результаты - только данные первого столбца (т.е. первый дочерний элемент 'RoleTypes', в этом примере - 'dev') и остальные столбцы пустые. Я также попытался создать .fo сначала с помощью самого fop (опция -foout), а затем с помощью FOP для создания PDF, но получил тот же результат, то есть данные отображаются только в столбец, который соответствует первому дочернему элементу элемента RoleTypes. Это ошибка с FOP (как кажется, признает Dyn: оценить, но не выполняет всю работу)?

Мне бы очень хотелось использовать одноступенчатый fop, чтобы мне не понадобилось развернуть дополнительные инструменты на клиентском компьютере (например, xsltproc и т. д.).

Вот критический сегмент таблицы стилей, которую я использовал:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  xmlns:dyn="http://exslt.org/dynamic">

<xsl:template match="projectteam">
 ...
 <fo:table table-layout="fixed" width="100%">
  <fo:table-column column-width="3cm"/>
  <xsl:for-each select="RoleTypes/*">
   <fo:table-column column-width="1cm"/>
  </xsl:for-each>

  <fo:table-body>
  <xsl:for-each select="member">
   <xsl:variable name="Member" select="."/>
   <fo:table-row>
    <fo:table-cell>
     <fo:block> <xsl:value-of select="name"/></fo:block>
    </fo:table-cell>

    <xsl:for-each select="../RoleTypes/*">
     <xsl:variable name="roleName" select="concat('$Member/', name(.))"/>
     <fo:table-cell><fo:block>

     <!-- This is where the problem is with fop; although the same statement works fine with xsltproc?? -->

      <xsl:value-of select="dyn:evaluate($roleName)"/>
     </fo:block></fo:table-cell>
    </xsl:for-each>
   </fo:table-row>
  </xsl:for-each>
  </fo:table-body>
 </fo:table>
</xsl:template>
</xsl:stylesheet>

Спасибо

Ответы [ 2 ]

2 голосов
/ 24 октября 2009

Это не отвечает общей проблеме использования dyn: define в FOP, но для этой конкретной схемы и задачи динамическая оценка не требуется. Вы можете использовать функцию name () для сопоставления имен узлов. Если вы замените внутренний цикл вашего примера на:

                    <xsl:for-each select="../RoleTypes/*">
                        <xsl:variable name="roleName" select="name(.)"/>
                        <fo:table-cell><fo:block>
                            <xsl:value-of select="$Member/*[name()=$roleName]"/>
                        </fo:block></fo:table-cell>
                    </xsl:for-each>

Вы получите желаемый результат.

1 голос
/ 06 октября 2009

Как отмечалось на http://markmail.org/message/np4t6fe4nsmr4vag, это не проблема FOP, а проблема с процессором XSLT по умолчанию, активным в вашей установке Java. Процессор XSLT, возможно, придется заменить явно, как описано здесь: http://xml.apache.org/xalan-j/faq.html#faq-N100EF

Конечно, вы также можете просто продолжать использовать xsltproc для генерации XSL-FO и затем подавать FOP файл FO.

...