Группировка XSLT в подгруппах с использованием generate-id() отбрасывает повторяющиеся ключи из более ранних групп.

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

<groups>
 <group id="1">
     <members>
         <member name="A">
           <udf @name="key">1</customId> 
         </member>
         <member name="B">
           <udf @name="key">1</customId> 
         </member>
     </members>
 </group>
 <group id="2">
     <members>
         <member name="C">
           <udf @name="key">1</customId> 
         </member>
         <member name="D">
           <udf @name="key">2</customId> 
         </member>
         <member name="E">
           <udf @name="key">3</customId> 
         </member>
     </members>
 </group>
</groups>

Результат, который я хочу произвести:

<group id="1">
    <member key="1" />
</group>
<group id="2">
    <member key="1" />
    <member key="2" />
    <member key="3" />
</group>

Я также выполняю другую обработку каждого элемента, но это тангенциально.

У меня есть шаблон, который запускает цикл и генерирует ключ:

<xsl:tempalte name="process">
   <xsl:for-each select="groups/group">
      <xsl:call-template name="getMembers"/>
   </xsl:for-each>
</xsl:tempalte>

<xsl:key name="keyId" match="member" use="udf/@name[.='key']/.."/>

<xsl:template name="getMembers>
    <xsl:for-each select="members/member[generate-id() = generate-id(key('keyId',udf/@name[.='key']/..))]">
      <!-- emits the grouped tags. -->
    </xsl:for-each>
</xsl:template>

Пока что я получаю с этим преобразованием:

<group id="1">
    <member key="1" />
</group>
<group id="2">
    <member key="2" />
    <member key="3" />
</group>

.. вы увидите отсутствующий ключ 1 из группы 2. Итак, я не понимаю, почему при втором вызове шаблона функция генерации идентификатора не выдает новый уникальный ключ для значения «1», даже хотя я вызываю генерировать идентификатор в контексте, как я думал, группы 2.


person JB.    schedule 25.08.2011    source источник


Ответы (1)


Вам нужно использовать составной ключ, который учитывает родителя group или members, например.

<xsl:key name="keyId" match="member" use="concat(generate-id(parent::members/parent::group), '|', udf[@name = 'key'])"/>

тогда, конечно, везде, где вы используете ключевую функцию, вам нужно убедиться, что вы вычисляете ее с тем же выражением, например.

<xsl:for-each select="members/member[generate-id() = generate-id(key('keyId', concat(generate-id(parent::members/parent::group), '|', udf[@name = 'key'])))]">
person Martin Honnen    schedule 25.08.2011
comment
спасибо - это было именно то, что мне нужно было сделать. я использовал parent::* в моем случае. - person JB.; 25.08.2011