Сортировка только определенных узлов XML - PullRequest
2 голосов
/ 14 января 2010

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

<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-файл, содержащий только узлы Transaction-Detail и их дочерние узлы. Когда я пытаюсь добавить дополнительную логику для копирования остальных узлов, сортировка прерывается.

Полагаю, у меня возникают проблемы с тем, чтобы обернуться вокруг теории и синтаксиса выполнения XSLT.

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

1 Ответ

4 голосов
/ 14 января 2010

Это сделает это: -

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...