doctype الديناميكي في تحويل XSLT (الاستخدام الصحيح لتعليمات النتيجة)

StackOverflow https://stackoverflow.com/questions/4275304

  •  28-09-2019
  •  | 
  •  

سؤال

أنا أستخدم XSLT وأحتاج إلى إنشاء Doctype ديناميكيًا في الإخراج المحول ، استنادًا إلى معلمة. أسمع أنه لا يمكن القيام بذلك باستخدام XSLT 1.0 ، ولكن يمكن مع الإصدار 2.0 ، باستخدام النتيجة بطاقة شعار.

حتى الآن ، من اتباع الإجابة في هذه سؤال ، لدي شيء مثل هذا:

    <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>

المشكلة مع ما ورد أعلاه لا يتم إنشاء الإخراج!

إذا قمت بإزالة علامات التحويل الواقعة من النتائج أعلاه ، فسيتم تطبيق التحويل الخاص بي وإخراج المستند ، كما هو متوقع.

أي أدلة؟ هل أستخدم علامة النتيجة بشكل صحيح؟


تحديث: استجابةً لبعض التعليقات ، هناك نسخة صغيرة تعمل ، وهي واحدة لا (حذف معلمة تعليمات النتيجة))

هذا يعمل (لا توجد حجة):

<?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>
هل كانت مفيدة؟

المحلول

كما اكتشفت أيضًا ، يدعم Xalan XSLT 1.0 فقط ، ولكن إذا كنت قد تغيرت إلى Saxon 9 ، فيمكنك بسهولة تحقيق ما تريد.

أيضًا ، بدلاً من تحديد المعلمات باستخدام إعدادات Doctype الخاصة بك ، يمكنك تحديد أ 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 ، هذا يجعل من السهل الحفاظ على تنسيقات الإخراج المختلفة إذا كان لديك الكثير منها.

نصائح أخرى

أثناء استخدامك لمحرك 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>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top