Существует ли “если - затем - еще” оператор в XPath?

private boolean include = true;
42
задан bluish 9 September 2011 в 13:00
поделиться

3 ответа

Да, в XPath 1.0 есть способ сделать это:

concat(
  substring($s1, 1, number($condition)      * string-length($s1)),
  substring($s2, 1, number(not($condition)) * string-length($s2))
)

Он основан на объединении двух взаимоисключающих строк, первая из которых пуста, если условие ложно ( 0 * длина строки (...) ), вторая пуста, если условие истинно. Это называется «методом Беккера» , приписываемым Оливеру Беккеру .

В вашем случае:

concat(
  substring(
    substring-before(//div[@id='head']/text(), ': '),
    1, 
    number(
      ends-with(//div[@id='head']/text(), ': ')
    )
    * string-length(substring-before(//div [@id='head']/text(), ': '))
  ),
  substring(
    //div[@id='head']/text(), 
    1, 
    number(not(
      ends-with(//div[@id='head']/text(), ': ')
    ))
    * string-length(//div[@id='head']/text())
  )
)

Хотя я бы попытался избавиться от всех »/ / " раньше.

Также существует вероятность, что // div [@ id = 'head'] вернет более одного узла.
Просто имейте в виду - использование // div [@ id = 'head'] [1] является более защитным.

61
ответ дан 26 November 2019 в 23:36
поделиться

The official language specification for XPath 2.0 on W3.org details that the language does indeed support if statements. See Section 3.8 Conditional Expressions, in particular. Along with the syntax format and explanation, it gives the following example:

if ($widget1/unit-cost < $widget2/unit-cost) 
  then $widget1
  else $widget2

This would suggest that you shouldn't have brackets surrounding your expressions (otherwise the syntax looks correct). I'm not wholly confident, but it's surely worth a try. So you'll want to change your query to look like this:

if (fn:ends-with(//div [@id='head']/text(),': '))
  then fn:substring-before(//div [@id='head']/text(),': ')
  else //div [@id='head']/text()

I do strongly suspect this may fix it however, as the fact that your XPath engine seems to be trying to interpret if as a function, where it is in fact a special construct of the language.

Finally, to point out the obvious, insure that your XPath engine does in fact support XPath 2.0 (as opposed to an earlier version)! I don't believe conditional expressions are part of previous versions of XPath.

23
ответ дан 26 November 2019 в 23:36
поделиться

Как насчет использования вместо этого fn: replace (string, pattern, replace)?

XPATH - это очень часто используется в XSLT, и если вы находитесь в такой ситуации и у вас нет XPATH 2.0, вы можете использовать:

  <xsl:choose>
    <xsl:when test="condition1">
      condition1-statements
    </xsl:when>
    <xsl:when test="condition2">
      condition2-statements
    </xsl:when>
    <xsl:otherwise>
      otherwise-statements
    </xsl:otherwise>
  </xsl:choose>
1
ответ дан 26 November 2019 в 23:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: