使用xslt将2个连续元素合并为1个
我是xslt新手,从几天前开始尝试不同的选项。 我对下面的场景有点不知所措(更多是因为我缺乏xslt方面的知识) 输入xml类似于:使用xslt将2个连续元素合并为1个,xslt,Xslt,我是xslt新手,从几天前开始尝试不同的选项。 我对下面的场景有点不知所措(更多是因为我缺乏xslt方面的知识) 输入xml类似于: <?xml version="1.0" encoding="UTF-8" standalone="no"?> <MAIN> <ProcessResponse> <ORDERNO>workorder123</ORDERNO> <NAME>BD-OC 102
<?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>
工作指令123
BD-OC 102
124
57
126
125
工作指令123
BD-OC 102
125
58
127
128
工作指令124
BD-OC 102
130
59
132
131
工作指令124
BD-OC 102
132
60
133
134
我期望的输出是这样的(基本上我希望每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>
工作指令123
BD-OC 102
124
57
126
125
125
58
127
128
工作指令124
BD-OC 102
130
59
132
131
132
60
133
134
注意:实际文件比这复杂得多,但基本思想是一样的,每2个连续块合并为一个(公共部分)
感谢您的帮助/指导/指点。尝试此基于关键点的解决方案:
将生成以下输出:
<?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>
工作指令123
BD-OC 102
124
57
126
125
125
58
127
128
工作指令124
BD-OC 102
130
59
132
131
132
60
133
134
要“合并两个连续的行”,请尝试以下操作:
<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>
哪个xslt版本?合并的规则是什么?是否真的连续,或者更多,因为ORDERNO是相同的?xslt版本1.0规则是:每两个连续(是,因为ORDERNO是相同的)元素(只有2个)将具有相同的ORDERNO。(虽然我想基于orderno做这件事会更通用),但这比我想要的要多(并不是说更多是件坏事)。我非常感激这个答案,我甚至知道xslt有这么多(我生活在java中,顺便说一句,这很深)。但是,您依赖于orderNo来对元素进行分组,我的实际xml要复杂得多,大约有8个公共字段(不共享xml,因为这可能是适当的)。因此,我最好的办法是合并两个连续的行(我正在生成的xml也是从db行中生成的,正如“MUENCHIAN”方法中提到的。有趣的是,我如何解释您的评论:“(虽然我猜基于orderno进行操作会更通用),但这比我想要的要多(不是说更多是坏事)。”按orderno进行分组可能就是您要寻找的。因此orderno对于两个元素来说不是唯一的?是的,我的错,这里的要点是实际xml大约有8个元素,它们的组合是唯一的。我创建了上面的伪xml来模拟类似的条件。我可以认为可行的解决方案是合并两个连续的元素(因为从db到xml的查询总是只返回2条记录,很少有公共记录(orderno、abc、xyz、message等)。很抱歉我的评论模棱两可。我想更新你的答案,但不允许说我需要15次才能做到。你的答案很棒,但目前对我不起作用。非常感谢,它很有魅力。我从你的回答中得到的概念是“position()mod 2=1”和“following sibling”我不知道,你在周末救了我的命。
<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>