2013-05-19 5 views
0

В приведенном ниже вводе мы должны проверить код поставщика, если он соответствует коду поставщика кода узла, тогда мы должны выполнить операцию суммирования на Quantity.otherwise, непосредственно направить количество.Выполнение операции SUM в XSLT

вход:

<Move-Afile> 
    <Afile> 
    <Item> 
    <suppliercode>1</suppliercode> 
     <PackNumber>1234</PackNumber> 
     <Quantity>12</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>2</suppliercode> 
     <PackNumber>567</PackNumber> 
     <Quantity>3</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>1</suppliercode> 
     <PackNumber>567</PackNumber> 
     <Quantity>8</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>3</suppliercode> 
     <PackNumber>126</PackNumber> 
     <Quantity>11</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>4</suppliercode> 
     <PackNumber>876</PackNumber> 
     <Quantity>32</Quantity> 
    </Item> 
    </Afile> 
</Move-Afile> 

Если код поставщика равно затем выполнить операцию суммы на количество, в противном случае непосредственно сопоставить количество.

выход:

<A> 
    <target> 
    <Item> 
    <suppliercode>1</suppliercode> 
     <PackNumber>1234</PackNumber> 
     <Quantity>20</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>2</suppliercode> 
     <PackNumber>567</PackNumber> 
     <Quantity>3</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>1</suppliercode> 
     <PackNumber>567</PackNumber> 
     <Quantity>20</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>3</suppliercode> 
     <PackNumber>126</PackNumber> 
     <Quantity>11</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>4</suppliercode> 
     <PackNumber>876</PackNumber> 
     <Quantity>32</Quantity> 
    </Item> 
    </target> 
</A> 

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

<varaible name=tempvar> 
<xsl:choose> 
<xsl:when suppliercode=suppliercode> 

<xsl:value-of select=sum(quntity)/> 

<xsl:when> 

<xsl:otherwise> 

<xsl:value-of select=quntity/> 

</xsl:otherwise> 

</xsl:choose> 

</variable> 
+0

Прошу прощения, но факт, что вы говорите: «Мне нужна логика суммы в отдельной временной переменной, как показано ниже», вовсе не означает, что это необходимо. Вам нужно либо представить реалистичный пример, который убеждает читателя, что это необходимо, или иным образом просто использовать предлагаемые решения. Были даны два решения, которые дают точно желаемый результат, не фиксируя сумму в промежуточной переменной. Это доказывает, что такой захват не нужен - если вы не убедите нас в обратном. –

+0

в моем требовании Я использую for loop. Где-то я хочу использовать эту логику, поэтому мне это нужно в отдельной переменной или, пожалуйста, предоставьте решение для каждого. – sum

ответ

0

Эта таблица стилей делает то, что вам нужно. Он копирует все элементы из Item вниз и имеет специальный шаблон для изменения значения Quantity путем добавления значений всех элементов Quantity из Item элементов, имеющих такое же значение suppliercode.

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

    <xsl:strip-space elements="*"/> 
    <xsl:output method="xml" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/> 

    <xsl:template match="/"> 
    <A> 
     <target> 
     <xsl:apply-templates select="Move-Afile/Afile/Item"/> 
     </target> 
    </A> 
    </xsl:template> 

    <xsl:template match="node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Quantity"> 
    <xsl:variable name="supplier-code" select="parent::Item/suppliercode"/> 
    <xsl:copy> 
     <xsl:value-of select="sum(ancestor::Afile/Item[suppliercode = $supplier-code]/Quantity)"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

выход

<A> 
    <target> 
     <Item> 
     <suppliercode>1</suppliercode> 
     <PackNumber>1234</PackNumber> 
     <Quantity>20</Quantity> 
     </Item> 
     <Item> 
     <suppliercode>2</suppliercode> 
     <PackNumber>567</PackNumber> 
     <Quantity>3</Quantity> 
     </Item> 
     <Item> 
     <suppliercode>1</suppliercode> 
     <PackNumber>567</PackNumber> 
     <Quantity>20</Quantity> 
     </Item> 
     <Item> 
     <suppliercode>3</suppliercode> 
     <PackNumber>126</PackNumber> 
     <Quantity>11</Quantity> 
     </Item> 
     <Item> 
     <suppliercode>4</suppliercode> 
     <PackNumber>876</PackNumber> 
     <Quantity>32</Quantity> 
     </Item> 
    </target> 
</A> 

Update Чтобы перевести сумму в переменную, прежде чем использовать его, вы можете заменить последний шаблон с этим

<xsl:template match="Quantity"> 
    <xsl:variable name="supplier-code" select="parent::Item/suppliercode"/> 
    <xsl:variable name="total" select="sum(ancestor::Afile/Item[suppliercode = $supplier-code]/Quantity)"/> 
    <xsl:copy> 
     <xsl:value-of select="$total"/> 
    </xsl:copy> 
    </xsl:template> 

который устанавливает t он имеет значение $total к сумме величин с тем же кодом suppplier.

+0

sum

+0

Мне нужна логика суммы в отдельной переменной. Мы можем сделать это, как и выше. Комментарий – sum

+0

Я добавил к своему ответу, чтобы сделать то, что вы просите. – Borodin

0

Это короткое и эффективное (с помощью ключа) преобразование:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kQuantityBySupplier" match="Quantity" use="../suppliercode"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/*"> 
    <A> 
    <target> 
     <xsl:apply-templates select="*/node()"/> 
    </target> 
    </A> 
</xsl:template> 

<xsl:template match="Quantity/text()"> 
    <xsl:value-of select="sum(key('kQuantityBySupplier', ../../suppliercode))"/> 
</xsl:template> 
</xsl:stylesheet> 

при нанесении на предоставленном документе XML:

<Move-Afile> 
    <Afile> 
    <Item> 
    <suppliercode>1</suppliercode> 
     <PackNumber>1234</PackNumber> 
     <Quantity>12</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>2</suppliercode> 
     <PackNumber>567</PackNumber> 
     <Quantity>3</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>1</suppliercode> 
     <PackNumber>567</PackNumber> 
     <Quantity>8</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>3</suppliercode> 
     <PackNumber>126</PackNumber> 
     <Quantity>11</Quantity> 
    </Item> 
    <Item> 
    <suppliercode>4</suppliercode> 
     <PackNumber>876</PackNumber> 
     <Quantity>32</Quantity> 
    </Item> 
    </Afile> 
</Move-Afile> 

производит разыскиваемый, правильный результат:

<A> 
    <target> 
     <Item> 
     <suppliercode>1</suppliercode> 
     <PackNumber>1234</PackNumber> 
     <Quantity>20</Quantity> 
     </Item> 
     <Item> 
     <suppliercode>2</suppliercode> 
     <PackNumber>567</PackNumber> 
     <Quantity>3</Quantity> 
     </Item> 
     <Item> 
     <suppliercode>1</suppliercode> 
     <PackNumber>567</PackNumber> 
     <Quantity>20</Quantity> 
     </Item> 
     <Item> 
     <suppliercode>3</suppliercode> 
     <PackNumber>126</PackNumber> 
     <Quantity>11</Quantity> 
     </Item> 
     <Item> 
     <suppliercode>4</suppliercode> 
     <PackNumber>876</PackNumber> 
     <Quantity>32</Quantity> 
     </Item> 
    </target> 
</A> 

Обратите внимание:

Временная сложность этого преобразования является линейным (O (N)). Это может быть на порядок более эффективным, чем повторное сканирование всех элементов, чтобы найти те, которые имеют данный suppliercode, который имеет квадратичную (O (N^2)) временную сложность.


Update:

ОР указал новое требование, что сумма или одной величины захватываться в переменной:

Просто измените это:

<xsl:template match="Quantity/text()"> 
    <xsl:value-of select="sum(key('kQuantityBySupplier', ../../suppliercode))"/> 
</xsl:template> 

в этот номер:

<xsl:template match="Quantity/text()"> 
    <xsl:variable name="vSum" select="sum(key('kQuantityBySupplier', ../../suppliercode))"/> 
    <xsl:value-of select="$vSum"/> 
</xsl:template> 
+0

<Название переменной имя = tempvar> sum

+0

мне нужна логика суммы в отдельном variable.can мы делаем, что, как выше комментарий. – sum

+0

@sum, Да, сумма может быть записана в переменной, однако в вопросе нет такого требования, и неясно, требуется ли вообще такое захват. Этот вопрос в его нынешнем виде полностью отвечает. Пожалуйста, отредактируйте вопрос или, желательно, задайте новый вопрос с новым требованием. –