Подтвердить что ты не робот

Элементы подсчета XSLT с заданным значением

Мне нужно подсчитать количество элементов в файле XML, которые имеют определенное значение (для проверки уникальности). Файл XML выглядит следующим образом:

РЕДАКТИРОВАТЬ: Я обновил оригинальный "упрощенный" XML с помощью действительно волосатого беспорядка. К сожалению, это сделает все предыдущие ответы действительно запутанными и неправильными, если не будет отредактирован.

<root>
  <ac>
   <Properties>
     <Property Name="Alive">
      <Properties>
        <Property Name="ID">
         <Properties>
           <Property Name="Value">
            <long>11007</long>
           </Property>
         </Properties>
        </Property>
      </Properties>
     </Property>
     <Property Name="Dead">
      <Properties>
        <Property Name="ID">
         <Properties>
           <Property Name="Value">
            <long>11008</long>
           </Property>
         </Properties>
        </Property>
      </Properties>
     </Property>
     ...
     <Property Name="MostlyDeadAllDay">
      <Properties>
        <Property Name="ID">
         <Properties>
           <Property Name="Value">
            <long>99001</long>
           </Property>
         </Properties>
        </Property>
      </Properties>
     </Property>
   </Properties>
  </ac>
</root>

Я пытаюсь определить переменную, чтобы увидеть, сколько из свойств на уровне Alive/Dead имеет длинное значение (ID), определенное в параметре шаблона. Что-то в этом направлении (хотя я подозреваю, что это неправильно)...

<xsl:param name="parPropId"/>
<xsl:variable name="countProperties">
   <xsl:value-of select="count(/root/ac/
      Properties/Property/
      Properties/Property[@Name = 'ID']/
      Properites/Property[@Name = 'Value']/long = $parPropId)"/>
</xsl:variable>

Может быть несколько элементов свойств, определенных на уровне "ID". Но я вполне уверен, что могу рассчитывать только на один элемент Property ( "Value" ) под "ID" и только один "длинный" элемент в разделе "Значение".

[отказ от ответственности] Тот, кто проектировал общий XML файл, я застрял в работе с REALLY, не знал, как структурировать XML (например, обратное использование атрибутов и элементов). Я боюсь, что мое мышление XSLT временно деформировалось:). [/Отказ от ответственности]

4b9b3361

Ответ 1

Этот XPath:

count(//Property[long = '11007'])

возвращает то же значение, что и:

count(//Property/long[text() = '11007'])

... за исключением того, что первый подсчет узлов Property, которые соответствуют критерию, и второй счетчик long дочерних узлов, которые соответствуют критерию.

В соответствии с вашим комментарием и чтением вашего вопроса несколько раз, я считаю, что вы хотите найти уникальность, основанную на сочетании критериев. Поэтому, на самом деле, я думаю, вы на самом деле проверяете несколько условий. Следующее будет работать:

count(//Property[@Name = 'Alive'][long = '11007'])

потому что это означает то же самое, что:

count(//Property[@Name = 'Alive' and long = '11007'])

Конечно, вы бы подменили значения параметров в своем шаблоне. Вышеприведенный код только иллюстрирует точку.

ИЗМЕНИТЬ (после редактирования вопроса)


Вы были совершенно правы в том, что XML ужасен. Фактически, это прямой CodingHorror кандидат! Мне пришлось продолжать пересчитывать, чтобы отслеживать "Свойство" node, на котором я был в данный момент. Я чувствую твою боль!

Здесь вы идете:

count(/root/ac/Properties/Property[Properties/Property/Properties/Property/long = $parPropId])

Обратите внимание, что я удалил все остальные проверки (для ID и Value). Они, похоже, не требуются, так как вы можете получить соответствующий node, используя иерархию в XML. Кроме того, вы уже упоминали, что проверка уникальности основана только на содержимом элемента long.

Ответ 2

Ваш xpath немного не работает:

count(//Property/long[text()=$parPropId])

Изменить: Церебрус совершенно справедливо указывает, что код в вашем OP (с использованием неявного значения node) абсолютно подходит для ваших целей. На самом деле, поскольку вы, скорее всего, хотите работать с "Свойством" node, а не с "длинным" node, он, вероятно, превосходит запрос //Property[long=$parPropId], чем text() xpath, хотя вы можете сделать для последнего на основании удобочитаемости.

Что я могу сказать, я немного устал сегодня:)

Ответ 3

<xsl:variable name="count" select="count(/Property/long = $parPropId)"/>

Не проверено, но я думаю, что это должно сработать. Я предполагаю, что узлы свойств являются прямыми дочерними элементами корня node и поэтому вынимают ваш селектор потомков для формирования