Това е моят 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, той помогна за този проблем и решението му работи, но не дава желания от мен резултат. Така че аз променях въпроса по прост начин.
Забележка: Въпросът отново е форматиран изцяло, за да се избегне объркване в същата нишка.
Отговори:
0 за отговор № 1<?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() > 1]">
<!-- here we have the next Email -->
<xsl:copy-of select="EMail" />
</xsl:for-each>
</CONTACT>
</xsl:template>
</xsl:stylesheet>
Трябва да работи :)
2 за отговор № 2
Използвайки стандартна техника за групиране, трябва само два шаблона (без бримки, без парами):
- Използвай комбиниран ключ събирам КОНТАКТ от Първо име и Второ име.
- След това приложете шаблоните на един сингъл КОНТАКТ за всяка група.
- Накрая, изтеглете електронна поща възли от ключа.
Последната ви трансформация:
<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 за отговор № 3
<?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>
Аз не изключих Арун - защото твоят изход има недостатък? в противен случай работи :)