#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:
«Если не указан ни один
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