Группировка и объединение двух контактов в XSLT1.0 - PullRequest
1 голос
/ 04 августа 2011

Это мой xml файл:

<?xml version="1.0" encoding="UTF-8"?>
<CONTACTS>

<CONTACT>
<FirstName>Arun</FirstName>
<LastName>Arun_Neelam</LastName>
<Email>nuraaa_iceee@yahoo.co.in</Email>
</CONTACT>

<CONTACT>
<FirstName>Arun</FirstName>
<LastName>Arun_Neelam</LastName>
<Email>nuraaa_iceee@gmail.com</Email>

</CONTACT>
</CONTACTS>

1.Как я могу объединить 2 вышеуказанных контакта в один контакт, принадлежащий одному человеку

Я бы хотел получить такой вывод:

<?xml version="1.0" encoding="windows-1250"?>
<CONTACTS>
    <CONTACT>
        <FirstName>Arun</FirstName>
        <LastName>Arun_Neelam</LastName>
        <Email>nuraaa_iceee@gmail.com</Email>
        <Email>nuraaa_iceee@yahoo.co.in</Email>
</CONTACT>
</CONTACTS>

Я не уверен, что смогу сделать это с current-group() and current-grouping-key(). Большое спасибо за вашу поддержку.

user639175, он помог в этой проблеме, и его решение работает, но не дает желаемого результата. Так что я изменил вопрос простым способом.

Примечание: я снова отформатировал вопрос, чтобы избежать путаницы в той же теме.

Ответы [ 3 ]

2 голосов
/ 06 августа 2011

Используя стандартную технику группировки, вам нужно всего два шаблона (без циклов, без параметров):

  • Используйте составной ключ для сбора CONTACT по FirstName и SecondName .
  • Затем примените шаблоны к одному CONTACT для каждой группы.
  • Наконец, извлеките узлы Email из ключа.

Ваше окончательное преобразование:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:key name="k_Contacts" 
        match="CONTACTS/CONTACT" 
        use="concat(FirstName,LastName)"/>

    <xsl:template match="CONTACTS">
        <xsl:copy>
            <xsl:apply-templates select="CONTACT[generate-id()=
                generate-id(key('k_Contacts',concat(FirstName,LastName))[1])]"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="CONTACT">
        <xsl:copy>
            <xsl:copy-of select="FirstName | LastName"/>
            <xsl:copy-of select="key('k_Contacts',concat(FirstName,LastName))
              /Email"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

В XSLT 2.0 вы можете использовать xsl:for-each-group; просто замените

<xsl:apply-templates select="CONTACT[generate-id()=
                generate-id(key('k_Contacts',concat(FirstName,LastName))[1])]"/>

с:

    <xsl:for-each-group select="CONTACT" group-by="concat(FirstName,LastName)">
        <xsl:apply-templates select="current-group()[1]"/>
    </xsl:for-each-group>
0 голосов
/ 05 августа 2011
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0"  encoding="windows-1250" indent="yes" />

<xsl:key name="groupName" match="//CONTACTS/CONTACT" use="concat(FirstName, LastName)" />

<xsl:template match="CONTACTS">

  <CONTACTS>
  <xsl:for-each select="//CONTACTS/CONTACT[generate-id() = generate-id( key('groupName', concat(FirstName, LastName))   [1] ) ]" >
    <xsl:sort select="CONTACT/EMail"  />

      <xsl:call-template name="group">
        <xsl:with-param name="k1" select="FirstName" />
        <xsl:with-param name="k2" select="LastName" />
      </xsl:call-template>

  </xsl:for-each>
  </CONTACTS>
</xsl:template> 

<xsl:template name="group">
<xsl:param name="k1" /> 
<xsl:param name="k2" /> 

  <CONTACT>
  <xsl:for-each select="//CONTACTS/CONTACT[FirstName = $k1][LastName = $k2][1]">

    <xsl:copy-of select="FirstName" />       
    <xsl:copy-of select="LastName" />       
    <!-- here we have the first Email -->
    <xsl:copy-of select="EMail" />       

  </xsl:for-each>
  <xsl:for-each select="//CONTACTS/CONTACT[FirstName = $k1][LastName = $k2][position() &gt; 1]">
    <!-- here we have the next Email -->

    <xsl:copy-of select="EMail" />       

  </xsl:for-each>
  </CONTACT>

</xsl:template> 
</xsl:stylesheet>

Должно работать:)

0 голосов
/ 05 августа 2011
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0"  encoding="windows-1250" indent="yes" />

<xsl:key name="groupName" match="//CONTACTS/CONTACT" use="concat(FirstName, LastName)" />

<xsl:template match="CONTACTS">

  <CONTACTS>
  <xsl:for-each select="//CONTACTS/CONTACT[generate-id() = generate-id( key('groupName', concat(FirstName, LastName))   [1] ) ]" >
    <xsl:sort select="CONTACT/EMail"  />

      <xsl:call-template name="group">
        <xsl:with-param name="k1" select="FirstName" />
        <xsl:with-param name="k2" select="LastName" />
      </xsl:call-template>

  </xsl:for-each>
  </CONTACTS>
</xsl:template> 

<xsl:template name="group">
<xsl:param name="k1" /> 
<xsl:param name="k2" /> 


  <xsl:for-each select="//CONTACTS/CONTACT[FirstName = $k1][LastName = $k2][1]">

    <xsl:copy-of select="." />       

  </xsl:for-each>

</xsl:template> 
</xsl:stylesheet>

Я не исключил Аруна - потому что у твоего примера есть недостаток? в противном случае это работает:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...