У меня проблема с группировкой нескольких ключей на основе критериев.Как слить несколько ключей с разными условиями
У меня 2 записей в формате XML. Документ 1 и Документ 2
Целью является создание таблицы с двумя разделами. То же самое, изменения.
Элементы, имеющие одинаковые элементы rec_no, part_no, ext_qty, которые находятся в обоих документах, должны поступать в подраздел Same. Элемент, который присутствует в обоих документах, но с изменением в rec_no, part_no, ext_qty должен находиться под пунктом изменения.
Теперь для этого я создал различные ключи на этих условиях. Теперь моя проблема заключается в том, как сгруппировать ключи для получения результатов.
Вот таблица с моими комментариями.
---------------------------------------------------------
Section RecNo Desc Doc-1 Qty Doc-2 Qty Total
---------------------------------------------------------
Same 111 Desc1 1 1 100
---------------------------------------------------------
Same Total 100
---------------------------------------------------------
Change 222 Desc2 2 3 500
Change 333 Desc3 3 3 600
Change 444 Desc4 6 4 600
---------------------------------------------------------
Change Total 1300
---------------------------------------------------------
Grand Total 1400
---------------------------------------------------------
Мой XML является:
<Logia>
<DocHeader>
<Document>
<Downto>
<part_no>111</part_no>
<rec_no>aaa</rec_no>
<desc>Desc1</desc>
<ext_qty>1</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>222</part_no>
<rec_no>bbb</rec_no>
<desc>Desc2</desc>
<ext_qty>2</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>333</part_no>
<rec_no>ccc</rec_no>
<desc>Desc3</desc>
<ext_qty>3</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>444</part_no>
<rec_no>ddd</rec_no>
<desc>Desc4</desc>
<ext_qty>6</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
</Document>
<Document>
<Downto>
<part_no>111</part_no>
<rec_no>aaa</rec_no>
<desc>Desc1</desc>
<ext_qty>1</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>222</part_no>
<rec_no>bbb</rec_no>
<desc>Desc3</desc>
<ext_qty>3</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>333</part_no>
<rec_no>bbb</rec_no>
<desc>Desc3</desc>
<ext_qty>3</ext_qty>
<mat_cost>100.00</mat_cost>
</Downto>
<Downto>
<part_no>444</part_no>
<rec_no>ddd</rec_no>
<desc>Desc4</desc>
<ext_qty>4</ext_qty>
<mat_cost>400.00</mat_cost>
</Downto>
</Document>
</DocHeader>
</Logia>
и мой XSLT является
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="MAT1PARTKEY" match="Document[1]/Downto" use="part_no" />
<xsl:key name="MAT2PARTKEY" match="Document[2]/Downto" use="part_no" />
<xsl:key name="MAT1RECKEY" match="Document[1]/Downto" use="rec_no" />
<xsl:key name="MAT2RECKEY" match="Document[2]/Downto" use="rec_no" />
<xsl:key name="MAT1QTYKEY" match="Document[1]/Downto" use="ext_qty" />
<xsl:key name="MAT2QTYKEY" match="Document[2]/Downto" use="ext_qty" />
<xsl:key name="MAT1COSTKEY" match="Document[1]/Downto" use="mat_cost" />
<xsl:key name="MAT2COSTKEY" match="Document[2]/Downto" use="mat_cost" />
<xsl:key name="MATERIALBYPARTNO" match="Document/Downto" use="part_no" />
<xsl:template match="/Logia/DocHeader">
<table border="1">
<!-- header -->
<tr>
<th>Section</th>
<th>PartNo</th>
<th>RecNo</th>
<th>Desc</th>
<th>Doc-1 Qty</th>
<th>Doc-2 Qty</th>
<th> Total</th>
</tr>
<!-- same -->
<xsl:variable name="same" select="Document[1]/Downto[key('MAT2RECKEY', part_no]" />
<xsl:apply-templates select="$same">
<xsl:with-param name="section">Same</xsl:with-param>
</xsl:apply-templates>
<xsl:variable name="same-total" select="sum($same/mat_cost)" />
<tr>
<td colspan="6">Same Total</td>
<th><xsl:value-of select="$same-total"/></th>
</tr>
<!-- change -->
<xsl:variable name="change" select="Document[1]/Downto[not(key('MAT2RECKEY', rec_no))]" />
<xsl:apply-templates select="$change">
<xsl:with-param name="section">Change</xsl:with-param>
</xsl:apply-templates>
<xsl:variable name="change-total" select="sum($change/mat_cost)" />
<tr>
<td colspan="6">Change Total</td>
<th><xsl:value-of select="$change-total"/></th>
</tr>
<!-- grand total -->
<tr>
<th colspan="6">Grand Total</th>
<th><xsl:value-of select="$same-total + $add-total + $delete-total"/></th>
</tr>
</table>
</xsl:template>
<xsl:template match="Downto">
<xsl:param name="section"/>
<xsl:if test="generate-id() = generate-id(key('MATERIALBYPARTNO', part_no)[1])">
<tr>
<td><xsl:value-of select="$section"/></td>
<td><xsl:value-of select="part_no"/></td>
<td><xsl:value-of select="rec_no"/></td>
<td><xsl:value-of select="desc"/></td>
<td><xsl:value-of select="sum(key('MAT1PARTKEY', part_no)/ext_qty)"/></td>
<td><xsl:value-of select="sum(key('MAT2PARTKEY', part_no)/ext_qty)"/></td>
<td><xsl:value-of select="sum(key('MATERIALBYPARTNO', part_no)/mat_cost)"/></td>
</tr>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Любая помощь приветствуется
Спасибо Рудольф. Я пробовал это, но я получаю записи с изменением количества в одних и тех же записях. || символ обозначает "или" условие право. Должен ли я использовать + для «и» условия – user2822294
Нет, || это просто разделитель строк, вы можете использовать любые символы, не ожидаемые в rec_no, part_no и ext_qty. –
Отличный рудольф. Теперь я понял. Огромное спасибо. Ценить это – user2822294