XSLT 在 ID 相同时合并数据 [英] XSLT Consolidating data when ID is the same
问题描述
我在使用 XML 并对其应用多个条件时遇到了一些问题.我有一个如下所示的输入 XML:
I am having some issues with consuming an XML and applying multiple conditions on it. I have an input XML that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ResultsType">
<result>
<resultSets>
<resultSet>
<row>
<column1>11111</column1>
<column2>0</column2>
<column3>imageId/111111</column3>
<column4>2012-04-03T10:11:22.187</column4>
</row>
<row>
<column1>11111</column1>
<column2>2</column2>
<column3>imageId/111112</column3>
<column4>2012-04-03T10:11:22.187</column4>
</row>
<row>
<column1>11111</column1>
<column2>2</column2>
<column3>imageId/111113</column3>
<column4>2012-04-03T10:11:22.187</column4>
</row>
<row>
<column1>22222</column1>
<column2>0</column2>
<column3>imageId/222222</column3>
<column4>2012-04-03T10:11:22.187</column4>
</row>
<row>
<column1>22222</column1>
<column2>2</column2>
<column3>imageId/222223</column3>
<column4>2012-04-03T10:11:22.187</column4>
</row>
</resultSet>
</resultSets>
</result>
</results>
但是我希望它看起来像这样:
However i would like it to look like this:
<?xml version="1.0" encoding="UTF-8"?>
<results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ResultsType">
<result>
<row>
<id>11111</id>
<lagrgeImage>imageId/111111</lagrgeImage>
<smallImage>imageId/111112</smallImage>
<smallImage>imageId/111113</smallImage>
</row>
<row>
<id>22222</id>
<lagrgeImage>imageId/222222</lagrgeImage>
<smallImage>imageId/222223</smallImage>
</row>
</result>
</results>
如您所见,有两个过滤条件:
As you can see there are two filtering condition:
如果 column2 = 0,则输出中需要 largeImage 标签,但是 column2 = 2 则输出中需要 smallImage 标签.
If column2 = 0 then largeImage tag is needed in the output however column2 = 2 then smallImage tag is needed in the output.
更新
下面的两个示例都运行良好,但是它们都在根目录中包含了出乎意料的命名空间.我得到的输出是:
Both of the examples below worked perfectly, however they are both including namespacing in the root that are unexpected. The output i get is:
<?xml version="1.0" encoding="utf-8"?>
<results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ResultsType">
<result>
<row>
<id>11111</id>
<largeImage>imageId/111111</largeImage>
<smallImage>imageId/111112</smallImage>
<smallImage>imageId/111113</smallImage>
</row>
<row>
<id>22222</id>
<largeImage>imageId/222222</largeImage>
<smallImage>imageId/222223</smallImage>
</row>
</result>
</results>
如何从上述输出中删除 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ResultsType"
?
How do i remove xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ResultsType"
from the above output?
推荐答案
如果您使用 XSLT2.0,您可以使用 for-each-group 函数.
If you are using XSLT2.0 you make use of the for-each-group function.
<xsl:for-each-group select="row" group-by="column1">
假设您的上下文是 resultSets,这将按 column1 中的id"对行进行分组.然后可以按如下方式获取当前分组密钥:
Assuming your context is resultSets this would group the rows by the 'id' in column1. The current grouping key could then be obtained as follows:
<xsl:value-of select="current-grouping-key()"/>
要获取组中的各个行,将它们转换为 largeImage 或 smallImage,您可以这样做
And to get the various rows in the group, to transform them to either largeImage or smallImage, you would do this
<xsl:apply-templates select="current-group()" />
这是完整的 XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.castiron.com//response">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="resultSets">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="resultSet">
<xsl:apply-templates select="@*"/>
<xsl:for-each-group select="row" group-by="column1">
<row>
<id><xsl:value-of select="current-grouping-key()"/></id>
<xsl:apply-templates select="current-group()" />
</row>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="row[column2='0']">
<largeImage><xsl:value-of select="column3" /></largeImage>
</xsl:template>
<xsl:template match="row">
<smallImage><xsl:value-of select="column3" /></smallImage>
</xsl:template>
<xsl:template match="@*|node()[not(self::*)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例 XML 时,输出如下
When applied to your sample XML, the following is output
<results xmlns="http://www.castiron.com//response">
<result>
<row>
<id>11111</id>
<largeImage>imageId/111111</largeImage>
<smallImage>imageId/111112</smallImage>
<smallImage>imageId/111113</smallImage>
</row>
<row>
<id>22222</id>
<largeImage>imageId/222222</largeImage>
<smallImage>imageId/222223</smallImage>
</row>
</result>
</results>
这篇关于XSLT 在 ID 相同时合并数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!