【问题标题】:Sorting only specific XML nodes仅对特定 XML 节点进行排序
【发布时间】:2010-01-14 20:52:01
【问题描述】:

我只需要对以下文件的<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-

【问题讨论】:

  • 您需要将 Transaction-Detail 节点集之前的节点保留在顶部,而将后面的节点保留在底部或不能将 Transaction-Detail 节点移动到 XMl 的底部? (顺便说一句,我假设出于遗留原因,您不能仅仅重新设计 XML,以便像 Product-Detail 和 Transaction-Detail 这样的东西每个都有一个包含父节点,因此它们没有具有不同标记名的兄弟姐妹)

标签: xslt sorting


【解决方案1】:

这样就可以了:-

<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>

【讨论】:

  • +1。我刚刚注意到您发布了我刚刚发布的完全相同 代码(我想我应该阅读您的第二个代码示例……)。删除我的答案以避免冗余。
  • 谢谢安东尼。它确实奏效了!不幸的是,我无法控制 xml 结构的创建,但这至少可以解决排序问题。
猜你喜欢
  • 1970-01-01
  • 2023-01-11
  • 1970-01-01
  • 2022-08-17
  • 2014-05-01
  • 2021-11-12
  • 2020-08-14
  • 2017-01-01
  • 1970-01-01
相关资源
最近更新 更多