doctype الديناميكي في تحويل XSLT (الاستخدام الصحيح لتعليمات النتيجة)
سؤال
أنا أستخدم 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'><!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>