xsl: как использовать параметр внутри «match»? - PullRequest
4 голосов
/ 25 мая 2011

У моего xsl есть параметр

<xsl:param name="halfPath" select="'halfPath'"/>

Я хочу использовать его внутри матча

<xsl:template match="Element[@at1='value1' and not(@at2='{$halfPath}/another/half/of/the/path')]"/>

Но это не работает. Я не могу использовать параметры внутри ''. Как это исправить / обойти это?

Ответы [ 4 ]

6 голосов
/ 25 мая 2011

Ну, вы можете использовать условную инструкцию внутри шаблона:

<xsl:template match="Element[@at1='value1']">
  <xsl:if test="not(@at2=concat($halfPath,'/another/half/of/the/path'))">
    .. do something
  </xsl:if>
</xsl:template>

Вам просто нужно знать, что этот шаблон будет обрабатывать все элементы, которые удовлетворяют первому условию.Если у вас есть другой шаблон, который обрабатывает элементы, соответствующие первому, но не второму, то используйте <xsl:choose> и поместите тело другого шаблона в блок <xsl:otherwise>.

Или XSLT2 может обработатьесли вы можете переключиться на процессор XSLT2.

5 голосов
/ 25 мая 2011

Спецификация XSLT 1.0 W3C запрещает ссылаться на переменные / параметры внутри шаблона совпадения . :

"Это ошибка для значенияатрибут match содержит переменнуюReferenceReference "

В XSLT 2.0 такого ограничения нет, поэтому используйте XSLT 2.0 .

Если по непреодолимым причинам используется XSLT2.0 невозможно, поместите полное тело инструкции <xsl:template> в <xsl:if>, где тест в сочетании с шаблоном сопоставления эквивалентен шаблону сопоставления XSLT 2.0, который содержит ссылку / ссылку на переменную / параметр.

В более сложном случае, когда у вас есть несколько шаблонов, совпадающих с узлом одного типа, но с разными предикатами, которые ссылаются на переменные / параметры, тогда вместо переноса нужно будет использовать перенос <xsl:choose>1020 *.

2 голосов
/ 07 февраля 2013

В этой теме был ответ на мой вопрос, но предложенное решение Flynn1179 было не совсем правильным для меня (YMMV).Так что попробуйте, как это предлагают люди, более опытные, чем я, но если это не сработает для вас, подумайте, как я это решил.Я использую xsltproc, который обрабатывает только XSL версии 1.0.

Мне нужно было соответствовать <leadTime hour="0024">, но используйте параметр: <xsl:param name="hour">0024</xsl:param>.Я обнаружил, что: <xsl:if test="@hour='{$hour}'"> не работает, несмотря на заявления здесь и в других местах, что это обязательный синтаксис для XSL v.1.0.Вместо этого более простой <xsl:if test="@hour=$hour"> выполнил свою работу.

Еще один момент: Dimitre предлагает выше поместить шаблон внутри оператора if.xsltproc пожаловался на это: вместо этого я поместил оператор if внутри шаблона:

<xsl:template match="leadTime">
  <xsl:if test="@hour=$leadhour">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:if>
</xsl:template>
1 голос
/ 25 мая 2011

В XSLT 2.0 вы можете ссылаться на глобальные переменные в шаблоне совпадения, но синтаксис проще, чем вы предполагаете:

<xsl:template match="Element[@at1='value1' and 
              not(@at2=$halfPath/another/half/of/the/path)]"/>

вместо

<xsl:template match="Element[@at1='value1' and 
              not(@at2='{$halfPath}/another/half/of/the/path')]"/>

Кроме того, семантика - это не то, чего вы ожидаете: переменная, указанная в lhs "/", должна содержать набор узлов, а не фрагмент выражения XPath.

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