XSLT добавить значение атрибута на основе другого значения


Как я могу добавить значения, основанные на другом значении?

<?xml version="1.0" encoding="UTF-8"?>
<items>
   <item id="A1" quantity="5">
      <info type="ram x1" import="CA" />
   </item>
   <item id="A2" quantity="3">
      <info type="ram x1" import="SA" />
   </item>
   <item id="A3" quantity="10">
      <info type="ram x2" import="AU" />
   </item>
</items>

Мне нужно добавить все величины, основанные на type например, мне нужен выход в виде,

Объем оперативной памяти x1=8 объем оперативной памяти x2=10

<?xml version="1.0" encoding="UTF-8"?>
<items>
        <details type="ram x1" quantity="8"/>
        <details type="ram x2" quantity="10"/>
</items>

Попытался для каждой группы сначала получить количество, чтобы посмотреть, работает ли оно,

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output method="html" indent="yes" />
   <xsl:template match="items">
      <xsl:for-each-group select="item" group-by="info/@type">
         <xsl:value-of select="sum(@quantity)" />
      </xsl:for-each-group>
   </xsl:template>
</xsl:stylesheet>
2 2

2 ответа:

Используйте функцию current-group(), т. е.:

<xsl:value-of select="sum(current-group()/@quantity)" />

@ Kirill Polishchuck уже дал хороший ответ, я хотел бы добавить полную таблицу стилей, чтобы проиллюстрировать это.

Он выводит XML, отформатированный так, как вы показали, что это должно быть. Помимо использования current-group(), Существует также интересное применение current-grouping-key(), которое извлекает значение, вызвавшее группировку текущих элементов.

Вы указали xsl:output method как HTML, но ожидаемый результат выглядит как XML. Поэтому я изменил его на выходной XML.

Таблица стилей

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

 <xsl:output method="xml" indent="yes" />

 <xsl:template match="items">
  <xsl:copy>
     <xsl:for-each-group select="item" group-by="info/@type">
        <details>
           <xsl:attribute name="type">
              <xsl:value-of select="current-grouping-key()"/>
           </xsl:attribute>
           <xsl:attribute name="quantity">
              <xsl:value-of select="sum(current-group()/@quantity)" />
           </xsl:attribute>
        </details>
     </xsl:for-each-group>
  </xsl:copy>
 </xsl:template>

</xsl:stylesheet>

Вывод

<?xml version="1.0" encoding="UTF-8"?>
<items>
  <details type="ram x1" quantity="8"/>
  <details type="ram x2" quantity="10"/>
</items>

Еще более сжатая (но более сложная) версия использует так называемые шаблоны значений атрибутов:

<xsl:for-each-group select="item" group-by="info/@type">
   <details type="{current-grouping-key()}" quantity="{sum(current-group()/@quantity)}"/>
</xsl:for-each-group>