Выберите один экземпляр текста из списка элементов XML с избыточным текстом - PullRequest
1 голос
/ 19 марта 2012

Мне нужно создать список фильтров, которые будут применены к списку новостей. У меня есть следующий кусок XML:

<filters>
   <filter>cars</filter>
   <filter>cars</filter>
   <filter>animals</filter>
   <filter>house</filter>
   <filter>sports</filter>
   <filter>cars</filter>
   <filter>house</filter>
</filters>

Что мне нужно сделать, это распечатать все различные фильтры для конечного пользователя. Поэтому я хочу запустить XML, но распечатать только один фильтр, чтобы фильтр под названием «автомобили» не распечатывался три раза, а только один раз. На самом деле XML-код, с которым я хочу закончить, следующий:

<filters>
   <filter>cars</filter>
   <filter>animals</filter>
   <filter>house</filter>
   <filter>sports</filter>
</filters>

Это приведет к одному экземпляру фильтра в XML.

Как я могу это сделать?

Заранее спасибо!

/ Kim

Ответы [ 2 ]

1 голос
/ 19 марта 2012

I.Решение XSLT 1.0.

Это преобразование:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kFilterByVal" match="filter" use="."/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match=
 "filter[not(generate-id()
            =
             generate-id(key('kFilterByVal', .))
             )
         ]"/>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<filters>
    <filter>cars</filter>
    <filter>cars</filter>
    <filter>animals</filter>
    <filter>house</filter>
    <filter>sports</filter>
    <filter>cars</filter>
    <filter>house</filter>
</filters>

выдает искомый правильный результат :

<filters>
   <filter>cars</filter>
   <filter>animals</filter>
   <filter>house</filter>
   <filter>sports</filter>
</filters>

Пояснение : Метод группировки по Мюнху .


II.Решение XSLT 2.0 :

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
     <filters>
       <xsl:for-each-group select="*" group-by=".">
         <xsl:sequence select="."/>
       </xsl:for-each-group>
     </filters>   
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к тому же XML-документу (см. Выше), получается тот же правильный результат.

Объяснение : Использование инструкции <xsl:for-each-group> XSLT 2.0.

1 голос
/ 19 марта 2012

Использование:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="k" match="filter" use="."/>

    <xsl:template match="filter[generate-id() != generate-id(key('k', .))]"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...