我需要连接在一个父节点中具有不同节点的节点。
我的XML如下所述:
<AllEmails>
<MailObject>
<ToEmail>abc@gmail.com</ToEmail>
<CCEmail>def@gmail.com</CCEmail>
<Content>Content 1</Content>
</MailObject>
<MailObject>
<ToEmail>abc@gmail.com</ToEmail>
<CCEmail>def@gmail.com</CCEmail>
<Content>Content 2</Content>
</MailObject>
<MailObject>
<ToEmail>geh@gmail.com</ToEmail>
<CCEmail>ijk@gmail.com</CCEmail>
<Content>Content 3</Content>
</MailObject>
<MailObject>
<ToEmail>geh@gmail.com</ToEmail>
<CCEmail>ijk@gmail.com</CCEmail>
<Content>Content 4</Content>
</MailObject>
</AllEmails>
我的XSL输出应该是这样的:
<UniqueEmails>
<MailObject>
<ToEmail>abc@gmail.com</ToEmail>
<CCEmail>def@gmail.com</CCEmail>
<Content>Content 1, Content 2</Content>
</MailObject>
<MailObject>
<ToEmail>geh@gmail.com</ToEmail>
<CCEmail>ijk@gmail.com</CCEmail>
<Content>Content 3, Content 4</Content>
</MailObject>
</UniqueEmails>
基本上它需要检查唯一的&#34;到&#34;和&#34; cc&#34;电子邮件地址并组合这些节点的内容,并提供输出与其内容的连接。预期的结果是不要将相同的内容重复发送到相同的电子邮件地址,而是连接并在电子邮件地址相同时将其作为一封电子邮件发送。
答案 0 :(得分:0)
一种解决方案是使用Muenchian Grouping。要匹配两个不同值具有相同值的元素,可以使用连接值的键:
<xsl:key name="mailkey" match="MailObject" use="concat(ToEmail,CCEmail)"/>
遵循XSLT
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="mailkey" match="MailObject" use="concat(ToEmail,CCEmail)"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="AllEmails">
<UniqueEmails>
<xsl:for-each select="MailObject[count(. | key('mailkey',
concat(ToEmail,CCEmail))[1]) = 1]">
<xsl:variable name="current" select="concat(ToEmail,CCEmail)"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()[not(name()='Content')]"/>
<Content>
<xsl:for-each select="//MailObject[concat(ToEmail,CCEmail)=$current]">
<xsl:value-of select="Content"/>
<xsl:if test="position() != last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</Content>
</xsl:copy>
</xsl:for-each>
</UniqueEmails>
</xsl:template>
</xsl:transform>
当应用于您的输入时,XML会生成输出
<UniqueEmails>
<MailObject>
<ToEmail>abc@gmail.com</ToEmail>
<CCEmail>def@gmail.com</CCEmail>
<Content>Content 1,Content 2</Content>
</MailObject>
<MailObject>
<ToEmail>geh@gmail.com</ToEmail>
<CCEmail>ijk@gmail.com</CCEmail>
<Content>Content 3,Content 4</Content>
</MailObject>
</UniqueEmails>
有关使用Muenchian方法进行分组的详细说明,请查看上面提供的链接中的文章
select="MailObject[count(. | key('mailkey', concat(ToEmail,CCEmail))[1]) = 1]"
循环中的xsl:for-each
选择具有值MailObect
和ToEmail
的串联值相同的所有唯一CCEmail
元素。在此循环中,将复制所有匹配的MailObject
元素,但省略子节点Content
:
<xsl:apply-templates select="@*|node()[not(name()='Content')]"/>
相反,会生成一个新的Content
元素,其中Content
个MailObject
个子元素的值具有相同的ToEmail
和CCEmail
值作为当前MailObject
:
<xsl:for-each select="//MailObject[concat(ToEmail,CCEmail)=$current]">
<xsl:value-of select="Content"/>
如果它不是最后一个元素,则使用position()
和last()
添加,
:
<xsl:if test="position() != last()">
<xsl:text>,</xsl:text>
</xsl:if>