уникальные значения строки из нескольких токенов с использованием xslt - PullRequest
0 голосов
/ 28 февраля 2012

У меня есть xml как

<programs>
 <program name="breaking laws" id="97;#ttt;#98;#tpl;#41;#fel" />
   <program name="advanced technology" id="89;#hjk;#95;#uio;#81;#lpk" />
 <program name="Emerging companies " id="88;#ple;#98;#tpl;#41;#fel" />
 <program name="breakinglaws" id="97;#ttt" />
 <program name="breakinglaws" id="97;#ttt;#98;#tpl;#81;#lpk" />
 <program name="breakinglaws" id="99;#hklo;#95;#uio" />
</programs>

Я хотел бы найти все уникальные идентификаторы текста, используя xslt 1.0 т.е.

ttt tpl fel hjk uio lpk ple hklo

Я пытался что-то сделать, используя ключ и выходные токены

<xsl:template name="output-tokens">
        <xsl:param name="list" />
        <xsl:variable name="newlist" select="concat(normalize-space($list), ' ')" />
        <xsl:variable name="first" select="substring-before($newlist, ';#')" />
        <xsl:variable name="remaining" select="substring-after($newlist, ';#')" />
        <id>
            <xsl:value-of select="$first" />
        </id>
        <xsl:if test="$remaining">
            <xsl:call-template name="output-tokens">
                <xsl:with-param name="list" select="$remaining" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

1 Ответ

1 голос
/ 28 февраля 2012

Вот одно из решений

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

   <xsl:template match="/programs">
      <!-- Variable containing concateneated list of all program elements**
      <xsl:variable name="allprograms">
         <xsl:apply-templates select="program"/>
      </xsl:variable>

      <!-- Call recursive template to split the list -->
      <xsl:call-template name="output-tokens">
         <xsl:with-param name="list" select="$allprograms" />
      </xsl:call-template>
   </xsl:template>

   <!-- Template used to concatenate all program elements -->
   <xsl:template match="program">
      <xsl:value-of select="concat(@id, ';#') "/>
   </xsl:template>

   <!-- Recursive template to split out list into unique elements -->
   <xsl:template name="output-tokens">
      <!-- List to split -->
      <xsl:param name="list"/>
      <!-- List of all currently processed elements -->
      <xsl:param name="newlist" select="';#'" />

      <!-- Get first variable in list, and also the remaining part of the list -->
      <xsl:variable name="first" select="substring-before($list, ';#')"/>
      <xsl:variable name="remaining" select="substring-after($list, ';#')"/>

      <!-- Check if first variable is not a number, and is not contained in currently processed list -->
      <xsl:if test="number($first) != number($first) and not(contains($newlist, concat(';#', $first, ';#')))">
         <id>
            <xsl:value-of select="$first"/>
         </id>
      </xsl:if>

      <!-- If there are still elements left in the list, call the template recursively -->
      <xsl:if test="$remaining">
         <xsl:call-template name="output-tokens">
            <xsl:with-param name="list" select="$remaining"/>
            <xsl:with-param name="newlist" select="concat($newlist, $first, ';#')"/>
         </xsl:call-template>
      </xsl:if>
   </xsl:template>
</xsl:stylesheet>

Идея состоит в том, чтобы сначала создать одну строку, содержащую все элементы программы, объединенные вместе.Затем вы вызываете рекурсивный шаблон, который получает первый элемент из списка, а затем проверяет, что он еще не был обработан (это достигается тем, что шаблон также содержит переменную уже обработанных элементов)

Когда XSLTПрименительно к вашему образцу XML выводится следующее:

<id>ttt</id>
<id>tpl</id>
<id>fel</id>
<id>hjk</id>
<id>uio</id>
<id>lpk</id>
<id>ple</id>
<id>hklo</id>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...