XSL: подсчет чисел не работает должным образом — Проблема с моим XPath?

#xslt #xpath #count

#xslt #xpath #подсчет

Вопрос:

Вот XML

 <row>
    <cell>blah blah</cell>

    <check>
        <option/>
        <option/>
        <option/>
        <option/>
        <option/>
        <option/>
    </check>
</row>
  

Вот XSL

 <xsl:template match="row">
    <xsl:variable name="inputLevel">
        <xsl:number count="option" level="any" from="."/>
    </xsl:variable>

    <xsl:value-of select="$inputLevel"/>
</xsl:template>
  

Все, что я получаю, это «0». http://www.w3schools.com/XPath/xpath_syntax.asp написано «.» означает текущий узел. Разве он не должен возвращать «6»?

Правка 1: Я хотел искать теги опций на ЛЮБОМ уровне, а не просто проверять. Следовало бы объяснить, но теги опций могут существовать на любом уровне ниже

Комментарии:

1. Хороший вопрос, 1. Смотрите мой ответ для подробного объяснения вашей проблемы и для полного, короткого и простого решения.

Ответ №1:

Если вы хотите посчитать потомков, option вам не следует использовать xsl:number , но:

 <xsl:variable name="inputLevel" select="count(.//option)"> 
  

Комментарии:

1. Это было решением. Чувак, которого я ТАК люблю! <3

2. Я попытался отметить, что это был ответ, но SO сказал «Подождите 5 минут», и я забыл вернуться. 😛 Но теперь это помечено. 😉

Ответ №2:

Я думаю, проблема в том, что выражение xpath option не будет соответствовать чему-либо в row элементе — попробуйте это вместо:

 <xsl:number count="check/option" level="any" from="." />
  

Для поиска option элементов на любом уровне используйте следующий синтаксис:

 <xsl:number count="//option" level="any" from="." />
  

Я не думаю, что from атрибут запрашивается, и level атрибут, вероятно, делает не то, что вы думаете (я также не уверен, что он делает …)

Комментарии:

1. Я хотел искать теги опций на ЛЮБОМ уровне, а не просто проверять. Следовало бы объяснить, но теги опций могут существовать на любом уровне ниже <строка>

2. На самом деле, атрибут count xsl: number является шаблоном, а не выражением XPath, и использование //option не будет иметь никакого значения, потому что в качестве шаблона «option» и «//option» соответствуют точно таким же узлам. Нет: чтобы найти ответ, просто прочитайте спецификацию для xsl: number. Вы воображаете, что это делает что-то совершенно отличное от того, что оно делает на самом деле.

Ответ №3:

Из спецификации XSLT 1.0 W3C:

«Если не указан ни один value атрибут, то xsl:number
element
вставляется число, основанное на положении текущего узла в исходном дереве.
Следующие атрибуты определяют, как должен быть пронумерован текущий узел:

level Атрибут указывает, какие уровни исходного дерева следует учитывать; он имеет значения single , multiple или any . Значение по умолчанию равно single .

count Атрибут — это шаблон, который указывает, какие узлы следует учитывать на этих уровнях. Если атрибут count не указан, то по умолчанию используется шаблон, который соответствует любому узлу с тем же типом узла, что и текущий узел, и, если текущий узел имеет расширенное имя, с тем же расширенным именем, что и текущий узел

Когда level="any" он создает список длины один, содержащий количество узлов, которые соответствуют count шаблону и принадлежат набору, содержащему текущий узел и все узлы на любом уровне документа, которые находятся перед текущим узлом в порядке документа, исключая любое пространство имен и узлы атрибутов (другими словами, объединение элементов осей previous и ancestor-или-self). Если указан from атрибут, то рассматриваются только узлы после первого узла перед текущим узлом, которые соответствуют шаблону from. «.

Из этого текста ясно, что учитываются только узлы, которые являются предками или предшествуют текущему узлу.

В этом вопросе текущий узел является узлом верхнего элемента row и имеет 0 узлов-предков и 0 предшествующих элементов.

Следовательно, возвращенный результат правильный!

Решение:

Использовать:

 count(descendant::option)
  

Результатом вычисления этого выражения является количество всех option элементов в документе, которые являются потомками текущего узла ( row элемента).

Комментарии:

1. @Alejandro: Спасибо. Не могли бы вы, пожалуйста, ответить на отправленное мной электронное письмо?

2. Извините. Я не проверил это направление заранее. Для улучшения есть запрос к дампу данных по адресу data.stackexchange.com/stackoverflow/q/99534