#xslt #xslt-1.0 #xslt-grouping
#xslt #xslt-1.0 #xslt-группировка
Вопрос:
Я пытаюсь сгруппировать все похожие записи на основе языка. Но я не могу сгруппировать в XSLT. Я использую функцию XSL KEY для группировки записи в XSLT. Я пытаюсь выполнить цикл и добавить записи каждой группы в одну группу.
У меня есть следующий входной xml.
<root>
<element name="David" language="German"></element>
<element name="Sarah" language="German"></element>
<element name="Isaac" language="English"></element>
<element name="Abraham" language="German"></element>
<element name="Jackson" language="English"></element>
<element name="Deweher" language="English"></element>
<element name="Jonathan" language="Hindi"></element>
<element name="Mike" language="Hindi"></element>
</root>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:key name="lang" match="element" use="@language"></xsl:key>
<xsl:template match="/">
<root>
<xsl:for-each select="key('lang',//element/@language)">
<Group>
<xsl:attribute name="name" select=".//@language"></xsl:attribute>
<member><xsl:value-of select=".//@name"/></member>
</Group>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
Ожидаемый результат :
<root>
<Group name="German">
<member>David</member>
<member>Sarah</member>
<member>Abraham</member>
</Group>
<Group name="English">
<member>Isaac</member>
<member>Jackson</member>
<member>Deweher</member>
</Group>
<Group name="Hindi">
<member>Jonathan</member>
<member>Mike</member>
</Group>
</root>
Фактический результат :
<root>
<Group name="German">
<member>David</member>
</Group>
<Group name="German">
<member>Sarah</member>
</Group>
<Group name="English">
<member>Isaac</member>
</Group>
<Group name="German">
<member>Abraham</member>
</Group>
<Group name="English">
<member>Jackson</member>
</Group>
<Group name="English">
<member>Deweher</member>
</Group>
<Group name="Hindi">
<member>Jonathan</member>
</Group>
<Group name="Hindi">
<member>Mike</member>
</Group>
</root>
Я получаю каждую запись отдельно.
Может кто-нибудь, пожалуйста, дайте мне знать, что пошло не так в XSL. Спасибо 🙂
Ответ №1:
Я внес некоторые изменения в вашу таблицу стилей. Это должно привести к ожидаемому результату:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:key name="lang" match="element" use="@language"></xsl:key>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each select="element[count(. | key('lang', @language)[1]) = 1]">
<Group name="{@language}">
<xsl:for-each select="key('lang', @language)">
<member><xsl:value-of select="@name"/></member>
</xsl:for-each>
</Group>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Первый цикл выбирает каждый уникальный язык (набор узлов размером 3) и создает контекст для внутреннего цикла. Внутренний цикл перебирает каждый элемент и выбирает только те, которые имеют тот же язык.
Группировка по-мюнхенски может показаться сложной для понимания, но вы всегда можете применить шаблон, показанный в этом руководстве, и вам не придется много думать. Я просто применил этот шаблон к вашему примеру.
ОБНОВЛЕНИЕ: вот решение без использования for-each
циклов:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:key name="lang" match="element" use="@language"></xsl:key>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="element[generate-id(.) = generate-id(key('lang', @language)[1])]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="element">
<Group name="{@language}">
<xsl:apply-templates select="key('lang', @language)" mode="member"/>
</Group>
</xsl:template>
<xsl:template match="element" mode="member">
<member><xsl:value-of select="@name"/></member>
</xsl:template>
</xsl:stylesheet>
Комментарии:
1. Есть ли какой-либо другой способ, которого мы можем достичь только одним циклом for.
2. ДА. На самом деле вы можете избавиться от них всех, используя шаблоны.
3. Спасибо. Это мне помогает.