Группировка ключей XSLT с учетом нескольких узлов на основе условия

<root>
   <Entry>
      <ID>1</ID>
      <Details>
         <Code>A1</Code>
         <Value>1000</Value>
         <Indicator>1</Indicator>
      </Details>
   </Entry>

   <Entry>
      <ID>2</ID>
      <Details>
         <Code>A2</Code>
         <Value>2000</Value>
         <Indicator>2</Indicator>
      </Details>
   </Entry>

   <Entry>
      <ID>3</ID>
      <Details>
         <Code>A3</Code>
         <Value>2500</Value>
         <Indicator>3</Indicator>
      </Details>
   </Entry>

   <Entry>
      <ID>4</ID>
      <Details>
         <Code>B1</Code>
         <Value>3000</Value>
         <Indicator>0</Indicator>
      </Details>
   </Entry>

   <Entry>
      <ID>5</ID>
      <Details>
         <Code>B2</Code>
         <Value>4000</Value>
         <Indicator>5</Indicator>
      </Details>
   </Entry>

   <Entry>
      <ID>6</ID>
      <Details>
         <Code>B3</Code>
         <Value>4500</Value>
         <Indicator>7</Indicator>
      </Details>
   </Entry>
</root>

У меня есть этот входной XML, который является продолжением моего более раннего вопроса. В основном я пытаюсь сгруппировать узлы на основе значения узла <Code>. Отображение выглядит следующим образом:

  1. Коды «A1», «A2» и «A3» должны быть сгруппированы вместе (скажем, кодовая группа «A»).
  2. Коды «B1», «B2» и «B3» должны быть сгруппированы вместе (скажем, группа кодов «B»).

[Эти коды являются общими и предназначены только для примера, а фактические коды отличаются и не так просты, пожалуйста, не воспринимайте их буквально]

В конце концов я суммирую значения, выходящие из <Value> узлов в этих группах, но в дополнение к моему предыдущему вопросу я суммирую только в том случае, если значение <Indicator> узла больше или равно 2

В настоящее время я использую этот XSLT (кредиты: michael.hor257k):

<xsl:stylesheet version="2.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="entry" match="Entry" use="Details/Code"/>

<xsl:template match="/root">
    <Output>
        <Code-group> A </Code-group>
        <Sum>
            <xsl:value-of select="sum(key('entry', ('A1', 'A2', 'A3'))/Details/Value)" />
        </Sum>
        <Code-group> B </Code-group>
        <Sum>
            <xsl:value-of select="sum(key('entry', ('B1', 'B2', 'B3'))/Details/Value)" />
        </Sum>
    </Output>
</xsl:template>

</xsl:stylesheet>

Что производит вывод следующим образом:

<Output>
  <Code-group> A </Code-group>
  <Sum> 5500 </Sum>

  <Code-group> B </Code-group>
  <Sum> 11500 </Sum>
</Output>

Но мне нужен этот вывод для сценария:

<Output>
  <Code-group> A </Code-group>
  <Sum> 4500 </Sum>

  <Code-group> B </Code-group>
  <Sum> 8500 </Sum>
</Output>

Это суммирует значение узла <Value> в соответствующих кодовых группах только тогда, когда <Indicator> больше или равно 2.

Есть ли способ включить этот реляционный оператор при определении ключа или он должен быть реализован как 2 ключа? Цените любой вклад

Заранее спасибо!


person Harish M    schedule 13.10.2020    source источник


Ответы (2)


Кажется, вам нужна только небольшая модификация:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="entry" match="Details[Indicator >= 2]" use="Code"/>

<xsl:template match="/root">
    <Output>
        <Code-group> A </Code-group>
        <Sum>
            <xsl:value-of select="sum(key('entry', ('A1', 'A2', 'A3'))/Value)" />
        </Sum>
        <Code-group> B </Code-group>
        <Sum>
            <xsl:value-of select="sum(key('entry', ('B1', 'B2', 'B3'))/Value)" />
        </Sum>
    </Output>
</xsl:template>

</xsl:stylesheet>
person michael.hor257k    schedule 13.10.2020

Просто используйте предикаты XPath

<xsl:template match="/root">
    <Output>
        <Code-group> A </Code-group>
        <Sum>
            <xsl:value-of select="sum(key('entry', ('A1', 'A2', 'A3'))/Details[Indicator >= 2 ]/Value)" />
        </Sum>
        <Code-group> B </Code-group>
        <Sum>
            <xsl:value-of select="sum(key('entry', ('B1', 'B2', 'B3'))/Details[Indicator >= 2 ]/Value)" />
        </Sum>
    </Output>
</xsl:template>
person Martin Honnen    schedule 13.10.2020