0

我是 xslt 的新手,几天以来一直在尝试不同的选择。我有点想不通以下场景(更多是因为我对 xslt 缺乏了解)

输入 xml 类似于:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MAIN>
    <ProcessResponse>
        <ORDERNO>workorder123</ORDERNO>
        <NAME>BD-OC 102</NAME>
        <FID>124</FID>
        <FNO>57</FNO>       
        <AID>126</AID>
        <BID>125</BID>

    </ProcessResponse>
    <ProcessResponse>
        <ORDERNO>workorder123</ORDERNO>
        <NAME>BD-OC 102</NAME>
        <FID>125</FID>
        <FNO>58</FNO>
        <AID>127</AID>
        <BID>128</BID>

    </ProcessResponse>
    <ProcessResponse>
        <ORDERNO>workorder124</ORDERNO>
        <NAME>BD-OC 102</NAME>
        <FID>130</FID>
        <FNO>59</FNO>       
        <AID>132</AID>
        <BID>131</BID>

    </ProcessResponse>
    <ProcessResponse>
        <ORDERNO>workorder124</ORDERNO>
        <NAME>BD-OC 102</NAME>
        <FID>132</FID>
        <FNO>60</FNO>
        <AID>133</AID>
        <BID>134</BID>

    </ProcessResponse>

</MAIN>

我期望的输出类似于(基本上我希望每 2 个连续的元素合并为 1,合并不常见的部分)。在程序语言中它应该很简单,但我在 xslt 中尝试了递归,但没有得到想要的结果。

转换后的输出:

<Response>
    <Process>
        <ORDERNO>workorder123</ORDERNO>
        <NAME>BD-OC 102</NAME>

        <F1>
            <FID>124</FID>
            <FNO>57</FNO>       
            <AID>126</AID>
            <BID>125</BID>
        </F1>

        <F2>
            <FID>125</FID>
            <FNO>58</FNO>
            <AID>127</AID>
            <BID>128</BID>
        </F2>

    </Process>

    <Process>
        <ORDERNO>workorder124</ORDERNO>
        <NAME>BD-OC 102</NAME>
        <F1>
            <FID>130</FID>
            <FNO>59</FNO>       
            <AID>132</AID>
            <BID>131</BID>
        </F1>
        <F2>
            <FID>132</FID>
            <FNO>60</FNO>
            <AID>133</AID>
            <BID>134</BID>
        </F2>

    </Process>


</Response>

注意:实际文件比这复杂得多,但基本思想是相同的,每 2 个连续的块合并为一个(公共部分)。

任何帮助/方向/指针表示赞赏。

4

2 回答 2

1

试试这个基于密钥的解决方案使用密钥分组:Muenchian 方法

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:key name="kOrderno" match="ProcessResponse" use="ORDERNO" />
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" >
                <xsl:with-param name="ch" select="h1" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ProcessResponse/ORDERNO"/>
    <xsl:template match="ProcessResponse/NAME"/>

    <xsl:template match="/*">
        <Response>
            <xsl:for-each select="ProcessResponse[count(. | key('kOrderno', ORDERNO)[1] ) =1] ">
                <Process>
                    <xsl:copy-of  select="ORDERNO"/>
                    <xsl:copy-of  select="NAME"/>
                    <xsl:variable name="on" select="ORDERNO" />
                    <xsl:for-each select=" key('kOrderno', $on)" >
                        <xsl:element name="F{position()}">
                            <xsl:apply-templates ></xsl:apply-templates>
                        </xsl:element>
                    </xsl:for-each>
                </Process>
            </xsl:for-each>
        </Response>
    </xsl:template>
</xsl:stylesheet>

这将生成以下输出:

<?xml version="1.0"?>
<Response>
  <Process>
    <ORDERNO>workorder123</ORDERNO>
    <NAME>BD-OC 102</NAME>
    <F1>


                <FID>124</FID>
                <FNO>57</FNO>
                <AID>126</AID>
                <BID>125</BID>

        </F1>
    <F2>


                <FID>125</FID>
                <FNO>58</FNO>
                <AID>127</AID>
                <BID>128</BID>

        </F2>
  </Process>
  <Process>
    <ORDERNO>workorder124</ORDERNO>
    <NAME>BD-OC 102</NAME>
    <F1>


                <FID>130</FID>
                <FNO>59</FNO>
                <AID>132</AID>
                <BID>131</BID>

        </F1>
    <F2>


                <FID>132</FID>
                <FNO>60</FNO>
                <AID>133</AID>
                <BID>134</BID>
        </F2>
  </Process>
</Response>
于 2013-06-13T15:46:05.517 回答
0

要“合并 2 个连续的行”,请尝试以下操作:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:key name="kOrderno" match="ProcessResponse" use="ORDERNO" />
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" >
                <xsl:with-param name="ch" select="h1" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ProcessResponse/ORDERNO"/>
    <xsl:template match="ProcessResponse/NAME"/>
    <xsl:template match="ProcessResponse/text()"/>

    <xsl:template match="/*">
        <Response>
            <xsl:for-each select="ProcessResponse">
                <xsl:if test="position() mod 2 = 1">
                <Process>
                    <xsl:copy-of  select="ORDERNO"/>
                    <xsl:copy-of  select="NAME"/>
                    <xsl:variable name="on" select="ORDERNO" />
                    <xsl:element name="F1">
                        <xsl:apply-templates />
                    </xsl:element>
                    <xsl:element name="F2">
                        <xsl:apply-templates select="following-sibling::ProcessResponse[1]/*" />
                    </xsl:element>
                </Process>
                </xsl:if>
            </xsl:for-each>
        </Response>
    </xsl:template>
</xsl:stylesheet>
于 2013-06-13T17:35:27.313 回答