2011-08-30 4 views
7

Im은 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> 
관련 문제