2013-12-05 3 views
1

У нас есть шаблон, как, например:Лучший способ подавить некоторый код, выполняемый в шаблоне при рефакторинге?

<xsl:template name = "MyTemplate"> 
    <!-- do some stuff--> 
    <xsl:apply-templates select = "Node"/> 
</xsl:template> 

Мы называем это с

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

Теперь мы собираемся реорганизовать это, так что этот внутренний применять шаблон не обязательно применять каждый раз, когда в шаблон называется. Мы хотим решить, следует ли применять его при вызове внешнего шаблона.

Однако мы не хотим (или не соглашаемся со мной по этому вопросу) проходить и реорганизовывать каждый существующий вызов внешнего шаблона, вместо этого мы должны реорганизовывать существующие приложения, где мы хотим, чтобы функциональность изменилась.

Там несколько способов, которые мы можем сделать это:

Во-первых, мы можем использовать либо XSLT-логическое значение, или строку, чтобы определить, должен ли он работать или нет.

Boolean:

<xsl:template name = "MyTemplate"> 
    <xsl:param name="UseNode" select = "true()"/> 
    <!-- do some stuff--> 

    <xsl:if test="$UseNode = true()"> 
     <xsl:apply-templates select = "Node"/> 
    </xsl:if> 
</xsl:template> 

Строка:

<xsl:template name = "MyTemplate"> 
    <xsl:param name="UseNode" select = 'true'/> 
    <!-- do some stuff--> 

    <xsl:if test="$UseNode = 'true'"> 
     <xsl:apply-templates select = "Node"/> 
    </xsl:if> 
</xsl:template> 

Во-вторых, мы можем либо установить его подавляют с использованием параметра или использование с помощью параметра.

Использование:

<xsl:template name = "MyTemplate"> 
    <xsl:param name="UseNode" select = "true()"/> 
    <!-- do some stuff--> 

    <xsl:if test="$UseNode = true()"> 
     <xsl:apply-templates select = "Node"/> 
    </xsl:if> 
</xsl:template> 

Используйте узел:

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

Не используйте узел:

<xsl:call-template name="MyTemplates"> 
    <xsl:with-param name="UseNode" select = "false()"/> 
</xsl:call-template> 

Подавить:

<xsl:template name = "MyTemplate"> 
    <xsl:param name="SuppressNode" select = "false()"/> 
    <!-- do some stuff--> 

    <xsl:if test="$SuppressNode = false()"> 
     <xsl:apply-templates select = "Node"/> 
    </xsl:if> 
</xsl:template> 

Используйте узел:

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

Не используйте узел:

<xsl:call-template name="MyTemplates"> 
    <xsl:with-param name="SuppressNode" select = "true()"/> 
</xsl:call-template> 

Какой самый лучший способ реорганизовать этот шаблон, и почему?

+0

nb. еще не проверял этот код - не уверен, что эти логические операции работают :) – dwjohnston

+0

Возможно, вам стоит проверить свой код. Если вы не знаете, работает оно или нет, как вы знаете, что это неправильно? –

ответ

1

Вы хорошо описали варианты; они все будут работать. За исключением очень необычных случаев, я ожидал бы, что все они будут неотличимы на практике (Дэвид Карлайл прав, что то, что отбрасывание времени во время компиляции во время выполнения имеет стоимость, но я ожидал бы, что стоимость будет незаметной большую часть времени, поэтому я не беспокойтесь об этом, если я не должен был).

Что лучше?

Тот, который сделает его самым легким для бедного присоска, который заканчивает чтение этого кода через три месяца, пытаясь исправить ошибку или расширить функциональность таблицы стилей. Вы, вероятно, лучший судья этого, в контексте.

(Для чего это стоит: я обычно использую строки «да» и «нет» в этих случаях, так как это то, как сам XSLT выполняет булевы, другие явно предпочитают реальные булевы, по причинам, которые Дэвид Карлайл имеет и в среднем я нахожу параметры, такие как SuppressNode, с отрицанием, встроенным в имя, 8,32% с большей вероятностью путают меня и заставляют меня перестать исправлять правильную полярность, чем параметры с положительным значением, например UseNode. были бы мной, я, вероятно, начинал бы с параметра UseNode по умолчанию, равного yes. Но затем я прочитал ответ Дэвида Карлайл и изменил его на два шаблона с именем MyTemplate и MyTemplate-SuppressNode, поскольку шаблон вызова - это одна строка в вызывающем, шаблон с параметрами - три.)

+0

Я дал галочку этому ответу, так как он более точно адресует вопрос, который является рефакторингом. – dwjohnston

3

Вам не нужно

<xsl:if test="$UseNode = true()"> 

просто

<xsl:if test="$UseNode"> 

если UseNode является (или может быть приведен к типу) логическое значение.

Аналогично $SuppressNode = false()" является not($SuppressNode)

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

<xsl:template name = "MyTemplate1"> 
    <!-- do some stuff--> 
</xsl:template> 

<xsl:template name = "MyTemplate2"> 
    <xsl:call-template name="MyTemplate1"/> 
    <xsl:apply-templates select = "Node"/> 
</xsl:template> 

Тогда вы можете просто позвонить MyTemplate1 или MyTemplate2 в зависимости. Если, конечно, в вашем реальном случае нет нескольких параметров и много разных комбинаций значений, в этом случае вам понадобится много именованных шаблонов, а не параметризованный, что было бы не так удобно.

+0

Re: ваш второй пункт. Да, в будущем может быть несколько таких узлов, которые вы хотите либо включить, либо выключить. – dwjohnston

+0

@dwjohnston трудно сказать без контекста, но, по крайней мере, в некоторых параметрах вашего параметра вы можете выразить, что такое выбор времени компиляции в тесте во время выполнения, который имеет некоторые издержки, если ваша система не оптимизирует его, но, возможно, это просто небольшой например, и в любом случае вам нужно решение времени выполнения, и значения ваших параметров зависят от входных данных (в этом случае вам определенно не нужны отдельные именованные шаблоны) –

Смежные вопросы