2010-01-13 7 views
2

мне нужно сортировать только <Transaction-Detail> узлы (по <tran-id> дочернего узла) из следующего файла:Сортировка только конкретные XML-узлы

<TransActDO clear="true" removed="false"> 
    <stmt-reason-code>1001</stmt-reason-code> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>788.20</txn-amt> 
    <txn-description>New Purchase</txn-description> 
    <tran-id>3271</tran-id> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>-68.20</txn-amt> 
    <txn-description>Return</txn-description> 
    <tran-id>27795</tran-id> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>0.00</txn-amt> 
    <txn-description>Comment</txn-description> 
    <transaction-reason-desc>No Reason</transaction-reason-desc> 
    <tran-id>13365</tran-id> 
    <transaction-reason-code>0</transaction-reason-code> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>343.45</txn-amt> 
    <txn-description>New Purchase</txn-description> 
    <tran-id>7558</tran-id> 
    </Transaction-Detail> 
    <Transaction-Detail clear="true" removed="false"> 
    <txn-amt>0.00</txn-amt> 
    <txn-description>Comment</txn-description> 
    <transaction-reason-desc>No Reason</transaction-reason-desc> 
    <tran-id>6512</tran-id> 
    <transaction-reason-code>0</transaction-reason-code> 
    </Transaction-Detail> 
    <account-no>123456789</account-no> 
    <payer-name>JOHN DOE</payer-name> 
    <Product-Detail clear="true" removed="false"> 
    <Name>WIDGET</Name> 
    <Amount>89.00</Amount> 
    </Product-Detail> 
    <Product-Detail clear="true" removed="false"> 
    <Name>NEWER WIDGET</Name> 
    <Amount>99.99</Amount> 
    </Product-Detail> 
    <stmt-reason-desc>Web Statement</stmt-reason-desc> 
    <type>Original</type> 
</TransActDO> 

Выход XML и нужно также скопировать все остальные узлы и атрибуты исходный файл. По сути, скопируйте все, просто отсортируйте узлы Transaction-Detail.

Я получил это далеко:

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

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

    <xsl:template match="TransActDO"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:apply-templates select="Transaction-Detail"> 
     <xsl:sort select="tran-id" data-type="number" order="ascending"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Это приводит к отсортирован XML-файл, содержащий только Транзакция-Detail узлы и их дочерние узлы. Когда я пытаюсь добавить дополнительную логику для копирования остальных узлов, сортировка прерывается.

Наверное, у меня возникли трудности с переносом моего мозга вокруг теории и синтаксиса выполнения XSLT.

Любая помощь очень ценится!
-nth-

+0

Вам нужны узлы, которые предшествовать множество транзакций детализации узлов оставаться на вершине, и те, которые следуют оставаться на дне или наклоняют Сделку-Detail узлы будут перемещены в нижней части XMl? (BTW Я предполагаю, что по устаревшим причинам вы не можете просто перепроектировать XML так, чтобы у таких вещей, как Product-Detail и Transaction-Detail, каждый из них содержал родительский узел, чтобы у них не было братьев и сестер с разными тэгами) – AnthonyWJones

ответ

4

Это будет делать это: -

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" encoding="Windows-1252" /> 

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

    <xsl:template match="TransActDO"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()[not(preceding-sibling::Transaction-Detail) and not(self::Transaction-Detail)]"/> 
      <xsl:apply-templates select="Transaction-Detail"> 
       <xsl:sort select="tran-id" data-type="number" order="ascending"/> 
      </xsl:apply-templates> 
      <xsl:apply-templates select="@*|node()[not(following-sibling::Transaction-Detail) and not(self::Transaction-Detail)]"/> 
    </xsl:copy> 
    </xsl:template> 


</xsl:stylesheet> 

Если вы не против перемещения Transaction-Detail элементы верхней или нижней части элемента TransActDO можно упростить внутренний набор от применять шаблоны для: -

  <xsl:apply-templates select="@*|node()[not(self::Transaction-Detail)]"/> 
      <xsl:apply-templates select="Transaction-Detail"> 
       <xsl:sort select="tran-id" data-type="number" order="ascending"/> 
      </xsl:apply-templates> 
+0

+1 , Я только что заметил, что вы разместили * тот же самый * код, который я только что опубликовал (думаю, я должен был прочитать ваш второй образец кода ...). Удаление моего ответа, чтобы избежать избыточности. – Tomalak

+0

Спасибо Энтони. Это действительно сработало! К сожалению, я не контролирую создание структуры xml, но это, по крайней мере, решит проблему сортировки. – nth

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