2012-04-20 3 views
1

Вот xml Я хочу преобразовать результат ниже с помощью xsl. Любая помощь пожалуйста. Это какая-то вещь, как структура каталогов Windows. Глубина каталога динамична.группировка данных xml с использованием xsl

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
<qc name="accounting" level="1"> 
    <qc name="fund" level="2"> 
     <qc name="v1_0" level="3"/> 
    </qc> 
</qc> 
<qc name="asset_allocation" level="1"> 
    <qc name="fund" level="2"> 
     <qc name="v1_0" level="3"/> 
    </qc> 
</qc> 
<qc name="asset_allocation" level="1"> 
    <qc name="fund" level="2"> 
     <qc name="v1_1" level="3"/> 
    </qc> 
</qc> 
<qc name="credit_quality" level="1"> 
    <qc name="account" level="2"> 
     <qc name="v1_0" level="3"/> 
    </qc> 
</qc> 
<qc name="credit_quality" level="1"> 
    <qc name="fund" level="2"> 
     <qc name="v1_0" level="3"/> 
    </qc> 
</qc> 
<qc name="credit_quality" level="1"> 
    <qc name="v1_0" level="2"/> 
</qc> 
<qc name="credit_quality" level="1"> 
    <qc name="v2_0" level="2"/> 
</qc> 
<qc name="portfolio" level="1"> 
    <qc name="credit_quality" level="2"> 
     <qc name="v1_0" level="3"/> 
    </qc> 
</qc> 
</root> 

В приведенном выше xml У меня есть имя каждого уровня. Я хочу сгруппировать одинаковые имена на одном уровне.

Результат:

<root> 
<qc name="accounting" level="1"> 
    <qc name="fund" level="2"> 
     <qc name="v1_0" level="3"/> 
    </qc> 
</qc> 
<qc name="asset_allocation" level="1"> 
    <qc name="fund" level="2"> 
     <qc name="v1_0" level="3"/> 
     <qc name="v1_1" level="3"/> 
    </qc> 
</qc> 
<qc name="credit_quality" level="1"> 
    <qc name="account" level="2"> 
     <qc name="v1_0" level="3"/> 
    </qc> 
    <qc name="fund" level="2"> 
     <qc name="v1_0" level="3"/> 
    </qc> 
    <qc name="v1_0" level="2"/> 
    <qc name="v2_0" level="2"/> 
</qc> 
<qc name="portfolio" level="1"> 
    <qc name="credit_quality" level="2"> 
     <qc name="v1_0" level="3"/> 
    </qc> 
</qc> 
</root> 
+0

Итак, где же XSL у вас есть? – Torious

ответ

2

Если вы можете использовать XSLT 2.0, делать, и использовать XSL: для-каждой группе команд.

Если вы застряли с XSLT 1.0, прочитайте о группировке Muenchian.

1

Быстрый взлом с использованием функций XSLT 1.0 и EXSLT может выглядеть так. Это, наверное, не самое элегантное решение, но оно должно работать.

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:func="http://exslt.org/functions" 
    xmlns:my="my-namespace" 
    extension-element-prefixes="func" 
    exclude-result-prefixes="my"> 

    <xsl:key name="qc-by-path" match="qc" use="my:path(.)"/> 

    <xsl:template match="root"> 
    <root> 
     <xsl:apply-templates/> 
    </root> 
    </xsl:template> 

    <xsl:template match="qc"> 
    <xsl:variable name="peers" select="key('qc-by-path', my:path(.))"/> 
    <xsl:if test="generate-id(.)=generate-id($peers[1])"> 
     <qc name="{@name}" level="{@level}"> 
     <xsl:apply-templates select="$peers/qc"/> 
     </qc> 
    </xsl:if> 
    </xsl:template> 

    <func:function name="my:path"> 
    <xsl:param name="qc"/> 
    <xsl:choose> 
     <xsl:when test="$qc/parent::qc"> 
     <func:result select="concat(my:path($qc/parent::qc),'/',$qc/@name)"/> 
     </xsl:when> 
     <xsl:otherwise> 
     <func:result select="$qc/@name"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </func:function> 
</xsl:stylesheet>