没有关系的分组 [英] Grouping with no relation

查看:38
本文介绍了没有关系的分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

XML:

<items>
    <transaction>
        <header>
            <col1>H</col1>
            <col2>XXXX</col2>
            <col3>YYY12345</col3>
            <col4/>
            <col5>YYY12345A1234</col5>
        </header>
    </transaction>
    <item>
        <col1>D</col1>
        <col2>1</col2>
        <col3>5358478</col3>
        <col4>-1.0000</col4>
        <col5>CA</col5>
    </item>
    <item>
        <col1>D</col1>
        <col2>2</col2>
        <col3>9477498</col3>
        <col4>1.0000</col4>
        <col5>CA</col5>
    </item>
    <item>
        <col1>D</col1>
        <col2>2</col2>
        <col3>9477498</col3>
        <col4>1.0000</col4>
        <col5>CA</col5>
    </item>
    <transaction>
        <header>
            <col1>H</col1>
            <col2>XXXX</col2>
            <col3>YYY12345</col3>
            <col4/>
            <col5>YYY12345A1236</col5>
        </header>
    </transaction>
    <item>
        <col1>D</col1>
        <col2>1</col2>
        <col3>1676600</col3>
        <col4>1.0000</col4>
        <col5>CA</col5>
    </item>
    <item>
        <col1>D</col1>
        <col2>2</col2>
        <col3>5602891</col3>
        <col4>1.0000</col4>
        <col5>CA</col5>
    </item>
    <item>
        <col1>D</col1>
        <col2>3</col2>
        <col3>7990401</col3>
        <col4>2.0000</col4>
        <col5>CA</col5>
    </item>
    <item>
        <col1>D</col1>
        <col2>4</col2>
        <col3>6985683</col3>
        <col4>1.0000</col4>
        <col5>CA</col5>
    </item>
    <item>
        <col1>D</col1>
        <col2>5</col2>
        <col3>9477498</col3>
        <col4>-1.0000</col4>
        <col5>CA</col5>
    </item>
    <item>
        <col1>D</col1>
        <col2>5</col2>
        <col3>9477498</col3>
        <col4>-1.0000</col4>
        <col5>CA</col5>
    </item>
</items>

所需的输出:

<items>
    <transaction>
        <header>
            <col1>H</col1>
            <col2>XXXX</col2>
            <col3>YYY12345</col3>
            <col4/>
            <col5>YYY12345A1234</col5>
        </header>
        <item>
            <col1>D</col1>
            <col2>1</col2>
            <col3>5358478</col3>
            <col4>-1.0000</col4>
            <col5>CA</col5>
        </item>
        <item>
            <col1>D</col1>
            <col2>2</col2>
            <col3>9477498</col3>
            <col4>1.0000</col4>
            <col5>CA</col5>
        </item>
        <item>
            <col1>D</col1>
            <col2>2</col2>
            <col3>9477498</col3>
            <col4>1.0000</col4>
            <col5>CA</col5>
        </item>
    </transaction>
    <transaction>
        <header>
            <col1>H</col1>
            <col2>XXXX</col2>
            <col3>YYY12345</col3>
            <col4/>
            <col5>YYY12345A1236</col5>
        </header>
        <item>
            <col1>D</col1>
            <col2>1</col2>
            <col3>1676600</col3>
            <col4>1.0000</col4>
            <col5>CA</col5>
        </item>
        <item>
            <col1>D</col1>
            <col2>2</col2>
            <col3>5602891</col3>
            <col4>1.0000</col4>
            <col5>CA</col5>
        </item>
        <item>
            <col1>D</col1>
            <col2>3</col2>
            <col3>7990401</col3>
            <col4>2.0000</col4>
            <col5>CA</col5>
        </item>
        <item>
            <col1>D</col1>
            <col2>4</col2>
            <col3>6985683</col3>
            <col4>1.0000</col4>
            <col5>CA</col5>
        </item>
        <item>
            <col1>D</col1>
            <col2>5</col2>
            <col3>9477498</col3>
            <col4>-1.0000</col4>
            <col5>CA</col5>
        </item>
        <item>
            <col1>D</col1>
            <col2>5</col2>
            <col3>9477498</col3>
            <col4>-1.0000</col4>
            <col5>CA</col5>
        </item>
    </transaction>
</items>

我正在尝试在 xslt 1.0 中做到这一点.我很难弄清楚如何在事务块内移动这些项目元素.

I am trying to do it in xslt 1.0. I'm having hard time figuring out how to move those item elements inside the transaction block.

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

推荐答案

在花了几分钟重新格式化您的示例输入和输出并使用 diff 之后,我认为您要做的只是移动 transaction 元素作为新的子元素添加到事务元素中.真的吗?

After spending a few minutes reformatting your sample input and output and using diff, I think what you are trying to do is just move all the siblings of a transaction element into the transaction element as new children. True?

将以下模板添加到您的样式表会生成一个样式表,该样式表会产生所需的输出.

Adding the following templates to your stylesheet produces a stylesheet which produces the desired output.

首先,items 的模板为其事务子项调用 apply-templates only(因为它们是唯一的输出应显示为输出子项 items 元素):

First, the template for items calls apply-templates only for its transaction children (since they are the only ones whose output should appear as children of the output items element):

<xsl:template match="items">
  <items>
    <xsl:apply-templates select="transaction"/>
  </items>
</xsl:template>

transaction 的模板首先在默认模式下为其子项调用 apply-templates.(这将处理 header 元素.)然后它在其紧邻的右兄弟节点上调用 apply-templates(它将成为 transaction 的第一个 item 子元素> 输出中的元素),处于特殊模式(此处称为 items).

The template for transaction calls apply-templates first for its children, in the default mode. (This handles the header element.) Then it calls apply-templates on its immediate right sibling (which will become the first item child of the transaction element in the output), in a special mode (here called items).

<xsl:template match="transaction">
  <transaction>
    <xsl:apply-templates/>
    <xsl:apply-templates 
        mode="items" 
        select="following-sibling::*[1]"/>
  </transaction>
</xsl:template>

items 模式专门用于收集给定交易的项目.它利用了项目都是兄弟的事实,所有项目都被逐字复制到输出,当找到下一个 transaction 兄弟时,项目序列结束.

The items mode is specialized for collecting the items of a given transaction. It exploits the fact that the items are all siblings, all are copied verbatim to the output, and the sequence of items ends when the next transaction sibling is found.

所以 items 模式下 item 的模板做了两件事:首先复制自己,然后应用模板,仍然在 items模式,到它的右兄弟.如果这是另一个项目,我们最终将再次评估此模板.然后再次.等等.(如果您有非常多的项目和弱 XSLT 优化器,则对堆栈内存的需求可能会攀升.)

So the template for item in the items mode does two things: first it copies itself, then it applies templates, still in items mode, to its immediate right sibling. If that's another item, we will end up evaluating this template again. And again. And so on. (If you have extremely numerous items and a weak XSLT optimizer, requirements for stack memory may climb.)

<xsl:template match="item" mode="items">
  <xsl:copy-of select="."/>
  <xsl:apply-templates 
      mode="items" 
      select="following-sibling::*[1]"/>
</xsl:template>

最终,item 元素的右兄弟将成为 transaction 元素.此时,我们希望递归停止,因此 transactionitems-mode 模板什么也不做.(它不需要处理事务,因为事务的默认模式模板会这样做.)

Eventually, the immediate right sibling of an item element is going to be a transaction element. At that point, we want the recursion to stop, so the items-mode template for transaction does nothing. (It doesn't need to handle the transaction, because the default-mode template for transaction will do so.)

<xsl:template match="transaction" mode="items"/>

右兄弟递归模式值得学习;它使这样的分组任务变得简单.

The right-sibling-recursion pattern is worth learning; it makes grouping tasks like this one simple.

这篇关于没有关系的分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆