Динамический тип документа в XSLT-преобразовании (правильное использование инструкции документа результата) - PullRequest
3 голосов
/ 25 ноября 2010

Я использую XSLT и мне нужно динамически генерировать тип документа в преобразованном выводе на основе параметра.Я слышал, что этого нельзя сделать с помощью XSLT 1.0, но можно с версией 2.0, используя тег result-document .

До сих пор от следованияответьте на этот вопрос, у меня есть что-то вроде этого:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" indent="yes"/>
    <xsl:param name="doctype.system" select="'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'" />
    <xsl:param name="doctype.public" select="'-//W3C//DTD XHTML 1.0 Strict//EN'" />
    <xsl:template match="/">
    <xsl:result-document doctype-public="{$doctype.public}" doctype-system="{$doctype.system}" method="html">
       <html>
          <head>
            <xsl:apply-templates select="report/head/node()"/>
          </head>
          <body>
             <!-- ommitted for brevity -->
          </body>
       </html>
    </xsl:result-document>
    </xsl:template>
    </xsl:stylesheet>

Проблема с вышеприведенным не генерируется!

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

Есть какие-нибудь подсказки?Правильно ли я использую тег result-document?


ОБНОВЛЕНИЕ : В ответ на некоторые комментарии приведена небольшая версия, которая работает, а другая - нет (безпараметризация инструкции результирующего документа)

Это работает (без результирующего документа):

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" indent="yes"/> 
<xsl:template match="/">
   <html>
      <head>

      </head>
      <body>

   </body>
   </html>   
</xsl:template>
</xsl:stylesheet>

Вывод:

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body></body>
</html>

Но это не дает никакого вывода:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" indent="yes"/> 
<xsl:template match="/">
<xsl:result-document doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" method="html">
   <html>
      <head>

      </head>
      <body>

   </body>
   </html>
</xsl:result-document>   
</xsl:template>
</xsl:stylesheet>

Ответы [ 2 ]

7 голосов
/ 25 ноября 2010

Как вы также узнали, Xalan поддерживает только XSLT 1.0, но если вы перешли на Saxon 9, вы можете легко достичь того, что вы хотите.

Кроме того, вместо определения параметров с помощью настроек типа документа вы можете определить xsl:output с именем и использовать в качестве формата в xsl:result-document:

<xsl:output name="my-xhtml-output" method="xml" encoding="UTF-8" indent="yes"
  doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
  doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/>

В вашем xsl:result-document затем вы используете этот формат вывода:

<xsl:result-document href="{$filename}" format="my-xhtml-output">
  ...
</xsl:result-document>

Imo, это упрощает поддержку различных форматов вывода, если у вас их много.

2 голосов
/ 25 ноября 2010

Поскольку вы используете движок XSLT 1.0, вам нужно будет создать динамический DOCTYPE, используя xsl:text:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes" />

  <xsl:param name="doctype.system" select="'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'" />
  <xsl:param name="doctype.public" select="'-//W3C//DTD XHTML 1.0 Strict//EN'" />

    <xsl:template match="/">
      <xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html PUBLIC "</xsl:text>
      <xsl:value-of select="$doctype.public" />
      <xsl:text disable-output-escaping='yes'>" "</xsl:text>
      <xsl:value-of select="$doctype.system" />
      <xsl:text disable-output-escaping='yes'>"></xsl:text>

      <!-- further processing here -->
      <html>

      </html>
    </xsl:template>
</xsl:stylesheet>
...