2011-08-30 164 views
7

我對xslt變換頗爲陌生,我需要一種轉換幫助。我需要通過它的屬性和列出每種屬性的父項將某些類型的所有節點分組。它是一種製作文件中某些東西用法的總結。我將介紹一個簡單的例子。
輸入:通過XSLT中的屬性值對XML節點進行分組

<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> 

所需的輸出:

<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> 

想法是,如果在許多節點的相同元素,他們具有相同的孩子-ID。 我需要找到所有使用的每個。 我發現這個問題XSLT transformation to xml, grouping by key這是有點類似,但有一個開始的所有作者的聲明,我沒有這樣的,是總是隻有一個孩子。

回答

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> 

輸出:

<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

非常感謝您!使用這個例子,我能夠對我的問題進行轉換! – Pax0r

+0

@ Pax0r,不客氣! –

1

您可以嘗試以下方法嗎?

<!-- 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> 
相關問題