Можно ли использовать динамическое выражение xPath в таблице стилей xslt? - PullRequest
6 голосов
/ 11 октября 2009

Я хотел бы использовать значение параметра xslt в выражении xpath. В частности, как часть вызова not() в выражении <xsl:if.

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- my_param contains a string '/foo/bar', passed in from ant -->
    <!-- the 'no' is just a default value -->
    <xsl:param name="my_param">no</xsl:param>
    <xsl:variable name="var_myparam" select="$my_param" />
    <!-- ... -->

    <!-- this works -->
    <xsl:if test="not(/foo/bar)" /> <!-- expression returns boolean true -->
        <!-- ... -->
    </xsl:if>

    <!-- I can't figure out how to do this the right way -->
    <!-- None of these appear to work -->
    <xsl:if test="not($var_myparam)" /> <!-- expression returns boolean false -->
        <!-- ... -->
    </xsl:if>       
    <xsl:if test="not({$var_myparam})" /> <!-- complains Required attribute 'test' is missing -->
        <!-- ... -->
    </xsl:if>       
    <xsl:if test="not({$myparam})" />   <!-- complains Required attribute 'test' is missing -->
        <!-- ... -->
    </xsl:if>       
    <xsl:if test="not($myparam)" />     <!-- expression returns boolean false -->
        <!-- ... -->
    </xsl:if>       

</xsl:transform>

Мне немного неясно, какой правильный синтаксис для создания динамического выражения xpath в таблице стилей xslt. Я также немного размыт о разнице между параметром, переменной и тем, как работает расширение обоих. Например, с параметрами я знаю, что иногда мне нужны скобки, а иногда нет.

<!-- when creating an element, it seems I need brackets -->
<xsl:element name="{$my_param}" />

<!-- when selecting an element value for the output stream, no brackets are needed -->
<xsl:value-of select="$my_param"/>

Любая общая / специальная помощь будет принята с благодарностью.

Ответы [ 3 ]

5 голосов
/ 11 октября 2009

Выезд http://www.exslt.org/. В частности, посмотрите на динамический: оценить модуль.

4 голосов
/ 12 октября 2009

XSLT не поддерживает динамическую оценку XPath - поэтому для этого нужно использовать функцию расширения, например EXSLT evaluate.

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

Редактировать

Об этих фигурных скобках: это шаблоны значений атрибутов (AVT). Они семантически эквивалентны в XSLT-преобразовании:

<foo>
   <xsl:attribute name="bar">
      <xsl:value-of select="XPathExpression"/>
   </xsl:attribute>
</foo>

<foo bar="{XPathExpression}"/>

Второй - просто ярлык для первого.

О переменных и параметрах: синтаксически, нет разницы между переменной и параметром; где бы вы ни ссылались на $foo в выражении XPath, оно будет работать одинаково независимо от того, определено ли foo xsl:variable или xsl:param.

Разница между ними заключается в том, как они населяются. Переменные заполняются в объявлении xsl:variable. Параметры объявляются в именованном шаблоне с помощью xsl:param, но они заполняются тем, что вызывает именованный шаблон, с использованием xsl:with-param, например ::

<xsl:call-template name="foo">
   <xsl:with-param name="bar" select="XPathExpression"/>
</xsl:call-template>

<xsl:template name="foo">
   <xsl:param name="bar"/>
   ...

Большим исключением из этого правила являются параметры, которые являются потомками xsl:stylesheet. Нет способа заполнить эти параметры внутри преобразования; они заполняются извне каким-либо (специфичным для среды) механизмом, вызывающим преобразование.

Довольно распространенный вариант использования компенсирует тот факт, что XSLT не имеет функции системной даты. Итак, вы увидите что-то вроде:

<xsl:stylesheet ...
   <xsl:param name="system-date"/>
   ...

и затем, при вызове преобразования, что-то вроде этого (в C #):

XsltArgumentList args = new XsltArgumentList();
args.AddParam("system-date", "", DateTime.Now.ToString("s"));
xslt.Transform(input, args, result);
3 голосов
/ 11 октября 2009

Попробуйте несколько вариантов этого:

<xsl:if test="not($var_myparam = 'no'))">
</xsl:if>

Проблема в том, как XPath оценивает логические значения. Любая непустая строка будет иметь значение true в XPath. Оформить заказ о xpath booleans .

Что касается других ваших вопросов ... Переменные и параметры в выражениях XPath действуют одинаково друг с другом. Обе ссылки имеют вид $ var.

Для любого атрибута XSLT с именем «select» вам не нужны скобки. Скобки используются в так называемых «шаблонах значений атрибутов». Вы используете их, когда XSLT ожидает строку, например:

<xsl:template match="name-a">
  <xsl:variable name="old-name" select="name(.)" />
  <name-b old-name="{$old-name}" new-attribute="hello"  />
</xsl:template>

Спецификация XSLT говорит о AVT , как и эта страница .

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