2011-08-30 5 views
7

xslt dönüşümlerinde oldukça yeni ve bir tür dönüştürme konusunda yardıma ihtiyacım var. Belirli türdeki tüm düğümleri, bu özelliklerden biri tarafından gruplandırılmalı ve her tür özniteliğin ana listesini listelemem gerekir. Belgedeki bazı şeylerin kullanımının bir özeti. Basitleştirilmiş örnek sunacağım.
Girdi:XML düğümlerini XSLT'deki özellik değerine göre gruplandırma

<root> 
<node name="node1"> 
    <somechild child-id="1"> 
</node> 
<node name="node2"> 
    <somechild child-id="2"> 
</node> 
<node name="node3"> 
    <somechild child-id="1"> 
</node> 
<node name="node4"> 
    <somechild child-id="2"> 
</node> 
<node name="node5"> 
    <somechild child-id="3"> 
</node> 
</root> 

İstenilen çıktı:

<root> 
<somechild child-id="1"> 
    <is-child-of> 
     <node name="node1" /> 
     <node name="node3" /> 
    </is-child-of> 
</somechild> 
<somechild child-id="2"> 
    <is-child-of> 
     <node name="node2" /> 
     <node name="node4" /> 
    </is-child-of> 
</somechild> 
<somechild child-id="3"> 
    <is-child-of> 
     <node name="node5" /> 
    </is-child-of> 
</somechild> 
</root> 

Fikir birçok düğümler aynı eleman ise aynı çocuk kimliğe sahip olmasıdır. Her biri tarafından kullanılan bulmam gerek. Bu soru XSLT transformation to xml, grouping by key'u benzer buluyorum, ancak benzer bir şekilde tüm yazarların bir beyanı var ve bende böyle bir şey yok, sadece bir çocuk.

cevap

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

    <xsl:key name="k" match="somechild" use="@child-id"/> 
    <xsl:key name="n" match="node" use="somechild/@child-id"/> 

    <xsl:template match="root"> 
     <xsl:copy> 
      <xsl:apply-templates 
       select="//somechild[generate-id(.) = generate-id(key('k', @child-id))]"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="somechild"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 

      <is-child-of> 
       <xsl:apply-templates select="key('n', @child-id)"/> 
      </is-child-of> 
     </xsl:copy> 

    </xsl:template> 

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

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

</xsl:stylesheet> 

Çıktı:

<root> 
    <somechild child-id="1"> 
    <is-child-of> 
     <node name="node1" /> 
     <node name="node3" /> 
    </is-child-of> 
    </somechild> 
    <somechild child-id="2"> 
    <is-child-of> 
     <node name="node2" /> 
     <node name="node4" /> 
    </is-child-of> 
    </somechild> 
    <somechild child-id="3"> 
    <is-child-of> 
     <node name="node5" /> 
    </is-child-of> 
    </somechild> 
</root> 
+0

çok teşekkür ederiz! Bu örneği kullanarak mayın problemi için dönüşüm yapabilirdim! – Pax0r

+0

@ Pax0r, Rica ederim! –

1

Aşağıdaki yaklaşımı deneyebilirsiniz?

<!-- select the current child id to filter by --> 
<xsl:variable name="id" select="somechild/@child-id"/> 
<!-- select the nodes which have a somechild element with the child-id to look for --> 
<xsl:for-each select="/root//some-child[@child-id = $id]/.."> 
    <!-- for each such node, do something --> 
</xsl:for-each>