Использование разных «select» для одного и того же шаблона (избегая повторения) - PullRequest
0 голосов
/ 13 февраля 2019

Вот упрощенная проблема:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/1999/xhtml"
    version="2.0">

    <xsl:param name="foo" select="'test'"/> <!-- 'test' can also be empty '' or whatever -->

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

    <xsl:template match="/">
        <html>
            <head>
                <title>bar</title>
            </head>
            <body>
                <xsl:choose>

                    <xsl:when test="string-length($foo)=0">
                        <ol>
                            <xsl:for-each select="something/something2"> <!-- SEE THIS? -->
                                <li>
                                    <xsl:call-template name="generic" />
                                </li>
                            </xsl:for-each>
                        </ol>
                    </xsl:when>

                    <xsl:otherwise>
                        <ol>
                            <xsl:for-each select="something/something2[tmp = $foo"]> <!-- SO MUCH REPETITION!! -->
                                <li>
                                    <xsl:call-template name="generic" />
                                </li>
                            </xsl:for-each>
                        </ol>
                    </xsl:otherwise>

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

Я думаю, что это довольно просто: как я могу избежать этого повторения?Я пытался использовать xsl:if для установки xsl:variable, но затем я не могу использовать переменную вне if, поэтому она становится бесполезной.

Аналогично, я хочу, чтобы <ol> применялся только тогда, когда<xsl:if test="count($varYouMightFigureOut) > 1">, иначе, это должен быть только <xsl:call-template name="generic" />, который вызывается сам по себе (for-each и <li> становятся неактуальными и не должны отображаться).Опять же: тривиальное решение включает в себя много повторений, но я бы предпочел избежать такой вещи.

Есть идеи?

Спасибо!

1 Ответ

0 голосов
/ 13 февраля 2019

Вы можете избежать этого повторения, полностью осознав внутреннюю красоту XSLT.
Используйте функцию шаблона, как показано в следующем примере:

Сократите центральный шаблон до его основных:

<xsl:template match="/">
    <html>
        <head>
            <title>bar</title>
        </head>
        <body>
            <xsl:apply-templates />
        </body>
    </html>
</xsl:template>

И добавить два подшаблона, реализующих последнее условие IF для гипотетического корневого элемента <root> (его имя должно совпадать с именем корневого элемента XML)

<xsl:template match="root">
   <xsl:call-template name="generic" />
</xsl:template> 

<xsl:template match="root[$varYouMightFigureOut > 1]">
   <ol>
       <xsl:apply-templates />
   </ol>
</xsl:template> 

Затем сведите две возможности xsl:choose к этим двум шаблонам:

<xsl:template match="something/something2[string-length($foo)=0]">
   <li>
       <xsl:call-template name="generic" />
   </li>
</xsl:template> 

<xsl:template match="something/something2[tmp = $foo]">
   <li>
       <xsl:call-template name="generic" />
   </li>
</xsl:template> 

(Вы можете добавить параметры к xsl:call-template при необходимости).

И дополните его «универсальным» шаблоном-заполнителем, используемым вышеупомянутыми шаблонами:

<xsl:template name="generic">
  <xsl:value-of select="normalize-space(.)" />
</xsl:template> 

Это решение исключает все ненужные повторения и использует мощь XSLT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...