2015-02-19 8 views
-1

Мне нужно объединить узлы, которые имеют разные узлы в одном родительском узле.concat уникальные дочерние узлы в xslt

Мой XML является, как указано ниже:

<AllEmails> 
<MailObject> 
<ToEmail>[email protected]</ToEmail> 
<CCEmail>[email protected]</CCEmail> 
<Content>Content 1</Content> 
</MailObject> 
<MailObject> 
<ToEmail>[email protected]</ToEmail> 
<CCEmail>[email protected]</CCEmail> 
<Content>Content 2</Content> 
</MailObject> 
<MailObject> 
<ToEmail>[email protected]</ToEmail> 
<CCEmail>[email protected]</CCEmail> 
<Content>Content 3</Content> 
</MailObject> 
<MailObject> 
<ToEmail>[email protected]</ToEmail> 
<CCEmail>[email protected]</CCEmail> 
<Content>Content 4</Content> 
</MailObject> 
</AllEmails> 

Моего выход XSL должен быть такой:

<UniqueEmails> 
<MailObject> 
<ToEmail>[email protected]</ToEmail> 
<CCEmail>[email protected]</CCEmail> 
<Content>Content 1, Content 2</Content> 
</MailObject> 
<MailObject> 
<ToEmail>[email protected]</ToEmail> 
<CCEmail>[email protected]</CCEmail> 
<Content>Content 3, Content 4</Content> 
</MailObject> 
</UniqueEmails> 

В основном это необходимо для проверки уникального «до» и «CC» адрес электронной почты и объединить содержимое этих узлов и предоставить вывод с конкатенацией их содержимого. Ожидаемый результат состоит в том, чтобы не отправлять один и тот же контент повторно на одни и те же адреса электронной почты, но конкатенация и отправка его в виде одного электронного письма, когда адреса электронной почты совпадают.

+0

Это не вопрос и решение. Есть другие места в Интернете, чтобы задать такой вопрос. Если у вас проблема с XSLT, вы можете задать здесь, но в ваших образцах нет даже одной строки XSLT :( – therealmarv

ответ

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>[email protected]</ToEmail> 
     <CCEmail>[email protected]</CCEmail> 
     <Content>Content 1,Content 2</Content> 
    </MailObject> 
    <MailObject> 
     <ToEmail>[email protected]</ToEmail> 
     <CCEmail>[email protected]</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> 
Смежные вопросы