كيفية استدعاء اسمه قوالب بناء على متغير ؟

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

  •  22-07-2019
  •  | 
  •  

سؤال

أنا لا أعرف إذا كان من الممكن, ولكن أنا أتساءل كيف نفعل ذلك...

دعونا نقول لدينا ما يلي XSL:

<xsl:template name="foo">
  Bla bla bla
</xsl:template>
...
<xsl:template name="bar">
  Bla bla bla
</xsl:template>
...
<xsl:template match="/">
  <xsl:if test="$templateName='foo'">
    <xsl:call-template name="foo"/>
  </xsl:if>
  <xsl:if test="$templateName='bar'">
    <xsl:call-template name="bar"/>
  </xsl:if>
</xsl:template>

هل من الممكن تغيير XSL إلى قراءة شيء من هذا القبيل...

<xsl:template match="/">
  <xsl:call-template name="$templateName"/>
</xsl:template>
هل كانت مفيدة؟

المحلول

لا، وهذا هو <الإضراب> لا يمكن لا يمكن مباشرة. اصطلاح استدعاء هي:

<xsl:call-template name="QName" />

وأين و QName كما :

QName ::= PrefixedName | UnprefixedName

PrefixedName   ::= Prefix ':' LocalPart
UnprefixedName ::= LocalPart

Prefix         ::= NCName
LocalPart      ::= NCName

وأساسا هذا يتلخص في "الأحرف فقط، أي تعبيرات". كما الإجابات تسليط الضوء على آخر، هناك <م> هي بطرق حقيقة أن تفعل شيئا ما يعادلها، إلا أن نهج مباشر / نهج ساذج لا تعمل.

نصائح أخرى

وليس من الممكن تماما كما تصفون، ولكن إذا كنت تريد أن تكون قادرة على اختيار القالب في وقت التشغيل استنادا إلى بعض القيمة التي قمت بتعيينها في أي مكان آخر، هناك خدعة للقيام بذلك. والفكرة هي أن يكون القالب يسمى أيضا تطابق عقدة مع اسم المقابلة في وضع متميز (بحيث لا خبط التحول العادي الخاص بك)، ومن ثم المباراة على ذلك. على سبيل المثال:

<xsl:stylesheet ... xmlns:t="urn:templates">

  <!-- Any compliant XSLT processor must allow and ignore any elements 
       not from XSLT namespace that are immediate children of root element -->
  <t:templates>
    <t:foo/>
    <t:bar/>
  </t:templates>

  <!-- document('') is the executing XSLT stylesheet -->     
  <xsl:variable name="templates" select="document('')//t:templates" />

  <xsl:template name="foo" match="t:foo" mode="call-template">
    Bla bla bla
  </xsl:template>

  <xsl:template name="bar" match="t:foo" mode="call-template">
    Bla bla bla
  </xsl:template>

  <xsl:template match="/">
    <xsl:variable name="template-name" select="..." />
    <xsl:apply-templates select="$templates/t:*[local-name() = $template-name]"
                         mode="call-template"/>
  </xsl:template>

لاحظ أنه يمكنك استخدام <xsl:with-param> في <xsl:apply-templates>، حتى تتمكن من القيام بكل شيء مع هذا الذي يمكن أن تفعله مع <xsl:call-template> عادي.

وأيضا، رمز أعلاه هو أطول بعض الشيء مما كنت قد تحتاج لأنه يحاول تجنب استخدام أي ملحقات XSLT. إذا المعالج الخاص بك يدعم exslt:node-set()، ثم يمكنك توليد مجرد العقد مباشرة باستخدام <xsl:element>، واستخدام node-set() لتحويل الناتج جزء شجرة إلى عقدة سهل لمباراة ضد، دون الحاجة إلى document('') الإختراق.

لمزيد من المعلومات، انظر FXSL - انها مكتبة البرمجة الوظيفية لXSLT التي تقوم على هذا المفهوم.

لإشارة أي شخص في المستقبل:

وهنا مثال العمل على أساس الإجابة بافل Minaev ل. أي فكر الأصلي من جهتي. ؛-) أنا تحولت إلى استخدام MSXML:-تعيين العقدة كما وصفها (أكثر أو أقل) بحيث أنه يعمل في. NET

.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.0">
    <xsl:variable name="templates">
        <templates>
            <foo />
            <bar />
        </templates>
    </xsl:variable>
    <xsl:template name="foo" match="foo" mode="call-template">
        <FooElement />
    </xsl:template>
    <xsl:template name="bar" match="bar" mode="call-template">
        <BarElement />
    </xsl:template>
    <xsl:template match="/">
        <Root>
            <xsl:variable name="template-name">bar</xsl:variable> <!-- Change this to foo to get the other template. -->
            <xsl:apply-templates select="msxsl:node-set($templates)/*/*[local-name() = $template-name]" mode="call-template" />
        </Root>
    </xsl:template>
</xsl:stylesheet>

التحديث:الروابط أدناه تم تحديث إلى نقطة web.archive.org -- للأسف ، IDEALLIANCE جعلت كل Exteme اللغات الترميزية وقائع المؤتمر غير متوفرة...في الوقت المناسب سوف تجد أكثر مكان دائم على هاتين المادتين.


وينفذ هذا FXSL.

هناك تفسيرات جيدة من المبادئ الرئيسية FXSL.

انظر المادتين التاليتين:

"البرمجة الوظيفية في XSLT باستخدام FXSL المكتبة"(XSLT 1.0), (PDF) في:

http://web.archive.org/web/20070710091236/http://www.idealliance.org/papers/extreme/proceedings/xslfo-pdf/2003/Novatchev01/EML2003Novatchev01.pdf

(HTML) في:

http://conferences.idealliance.org/extreme/html/2003/Novatchev01/EML2003Novatchev01.html



"العليا البرمجة الوظيفية مع XSLT 2.0 و FXSL"(PDF) في:

http://web.archive.org/web/20070222111927/http://www.idealliance.org/papers/extreme/proceedings/xslfo-pdf/2006/Novatchev01/EML2006Novatchev01.pdf

(HTML) في:http://conferences.idealliance.org/extreme/html/2006/Novatchev01/EML2006Novatchev01.html



باستخدام FXSL لقد كنت قادرا على حل بسهولة وأناقة العديد من المشاكل التي يبدو "مستحيلا XSLT".يمكن للمرء أن يجد الكثير من الأمثلة هنا.

وأعتقد أنه أكثر أو أقل نفس المشكلة كما كنت. كان لي "الخارجي" قالب ويريد الدعوة الى مختلف "الداخلية" قالب اعتمادا على بعض مجموعة متغير في وقت التشغيل. لقد وجدت سؤالك غوغلينغ عن وسيلة لديك <xsl:call-template> ديناميكية. I حلها باستخدام <xsl:apply-templates> بدلا من ذلك، على النحو التالي.

ووXML المدخلات (ولدت في وقت التشغيل) يحتوي على شيء على غرار:

<template name="template_name_1"/>

ووXSL في القالب "الخارجية" له:

<xsl:apply-templates select="template"/>

(يشير select="template" في هذا تطبيق قوالب إلى العلامة <template> في XML الإدخال)

وأخيرا "الداخلية" القالب الذي أردت أن تشمل نتيجة للقيمة السمة name في بلدي XML، يبدو مثل:

<xsl:template match="template[@name='template_name_1']">
    <!-- XSL / XHTML goes here -->
</xsl:template>

(مرة أخرى، تشير match="template[@name='xyz']" إلى select="template" سابقة، وهذا بدوره إلى العلامة <template> والسمة name لها في XML الإدخال)

في هذه الطريقة وأنا يمكن أن يكون ديناميكيا "ودعا" قالب ببساطة عن طريق التحكم من وجهة نظري XML الإدخال.

وهذا قد لا يكون نفس المشكلة كما تحاول حل ولكن اعتقد انها قريبة جدا، وأبسط بكثير من الحلول FSXL المذكورة في مكان آخر على هذه الصفحة.

وماذا عن هذا واحد:؟

  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

      <xsl:template match="xsl:template[@name='foo']" name="foo">
    Bla bla bla foo
      </xsl:template>

      <xsl:template match="xsl:template[@name='bar']" name="bar">
    Bla bla bla bar
      </xsl:template>

      <xsl:template match="/">
        <xsl:variable name="templateName" select="'bar'"/>
        <xsl:apply-templates select="document('')/*/xsl:template[@name=$templateName]"/>
        <xsl:apply-templates select="document('')/*/xsl:template[@name='foo']"/>
      </xsl:template>

    </xsl:stylesheet>

ويمكنك تبسيط "الدعوة" من القالب باستخدام متغير بالمثل كما هو موضح في مساهمة سابقة:

<xsl:variable name="templates" select="document('')/*/xsl:template"/> 

<xsl:apply-templates select="$templates[@name=$templateName]"/>
<xsl:apply-templates select="$templates[@name='foo']"/>

لاحظ أن <xsl:with-param> اختياري يمكن استخدامها على النحو المعتاد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top