2010-08-15 2 views
2

Я ищу XSL для сортировки и группировки XML по узлу и суммирования другим узлом. Мне нужно будет использовать XSLT 1.0.Как отсортировать XMl с помощью XSLT 1.0?

Вот мой XML. После сортировки мне нужно, чтобы новый XML был отсортирован и сгруппирован по <TransCode>, и все <TransAmt> следует суммировать для каждой группы. Я ищу XSL для выполнения этой задачи. Любая помощь приветствуется. После сортировки новый XML должен иметь только три узла, отсортированные в порядке возрастания <TransCode>. Все <TransAmt> необходимо добавить вместе.

Вот мой XML:

<Transactions> 
<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>12.30</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0002</TransCode> 
    <TransType>Cash</TransType> 
    <TransAmt>26.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>25.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0015</TransCode> 
    <TransType>FinanceCharge</TransType> 
    <TransAmt>25.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0002</TransCode> 
    <TransType>Cash</TransType> 
    <TransAmt>50.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>40.00</TransAmt> 
</Transaction> 
</Transactions> 
+0

Вы просите нас написать свой XSL для вас? Возможно, вы можете опубликовать XSL, с которым вы столкнулись, и сообщить нам, какие у вас проблемы и проблемы? Образец выходного документа, который вы хотите, также поможет ответить на вопрос. – Oded

+0

Хороший вопрос (+1). См. Мой ответ для полного и эффективного решения и объяснения ключевых идей. :) –

ответ

0

XSL имеет встроенный сортировки через <xsl:sort> элемент, и суммируя с помощью XPath sum функции.

Оба они поддерживаются в XSLT 1.0.

Какие проблемы вы используете?

1

Это преобразование:

<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="kTransByCode" 
    match="Transaction" use="TransCode"/> 

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

<xsl:template match="/Transactions"> 
    <Transactions> 
    <xsl:apply-templates select= 
    "Transaction[generate-id() 
       = 
       generate-id(key('kTransByCode', 
            TransCode 
           )[1] 
          ) 
       ] 
    "> 
    <xsl:sort select="TransCode" data-type="number"/> 
    </xsl:apply-templates> 
    </Transactions> 
</xsl:template> 

<xsl:template match="TransAmt"> 
    <TransAmt> 
    <xsl:value-of select= 
    "sum(key('kTransByCode',../TransCode)/TransAmt)"/> 
    </TransAmt> 
</xsl:template> 
</xsl:stylesheet> 

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

<Transactions> 
<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>12.30</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0002</TransCode> 
    <TransType>Cash</TransType> 
    <TransAmt>26.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>25.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0015</TransCode> 
    <TransType>FinanceCharge</TransType> 
    <TransAmt>25.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0002</TransCode> 
    <TransType>Cash</TransType> 
    <TransAmt>50.00</TransAmt> 
</Transaction> 

<Transaction> 
    <TransCode>0008</TransCode> 
    <TransType>Purchase</TransType> 
    <TransAmt>40.00</TransAmt> 
</Transaction> 
</Transactions> 

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

<Transactions> 
    <Transaction> 
     <TransCode>0002</TransCode> 
     <TransType>Cash</TransType> 
     <TransAmt>76</TransAmt> 
    </Transaction> 
    <Transaction> 
     <TransCode>0008</TransCode> 
     <TransType>Purchase</TransType> 
     <TransAmt>77.3</TransAmt> 
    </Transaction> 
    <Transaction> 
     <TransCode>0015</TransCode> 
     <TransType>FinanceCharge</TransType> 
     <TransAmt>25</TransAmt> 
    </Transaction> 
</Transactions> 

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

  1. Muenchian метод группировки используется.

  2. Использование ключей позволяет легко и эффективно суммировать на каждый транскод.

  3. Для того, чтобы скопировать как можно больше элементов, используется символ, и его переопределяют шаблоны, соответствующие элементам, которые будут отличаться от результата.

+0

+1 Хороший ответ! Но, я думаю, это может быть менее многословным, если вы сопоставляете «первый в своем роде» «Транзакция» и «TransAmt/text()». Я говорю это, потому что некоторые люди жалуются на XSLT, было многословным, вы знаете. – 2010-08-16 20:08:34

Смежные вопросы