2012-06-14 2 views
2

질문은 이것과 비슷합니다. earlier question 어떤 Dimitre가 이미 대답 했습니까? 응답 XML에는 약간의 수정이 있습니다. 그러나 이번에는 반복 블록에서 하나의 요소를 가져와야합니다. xsl 키 기능을 사용할 수 있는지 확실하지 않습니다.중복을 제거하기 위해 변형, 중복에서 하나의 요소 가져 오기

내 입력 XML

<M> 
    <a> 
     <b> 
     <c f="123"> 
      <key>Al</key> 
      <e NO="678"> 
       <f>Y</f> 
       <g> 
        <h>FTO</h> 
       </g> 
      </e> 
     </c> 
     </b> 
    </a> 
    <a> 
     <b> 
     <c f="123"> 
      <key>Al</key> 
      <e NO="678"> 
       <f>Y</f> 
       <g> 
        <h>FTO</h> 
       </g> 
      </e> 
     </c> 
     </b> 
    </a> 
    <a> 
     <b> 
     <c f="567"> 
      <key>Al</key> 
      <e NO="678"> 
       <f>Y</f> 
       <g> 
        <h>FTO</h> 
       </g> 
      </e> 
     </c> 
     </b> 
    </a> 
    <a> 
     <b> 
     <somethingelse/> 
     </b> 
    </a> 
</M> 

내 원하는 출력 XML은 - 중복을 제거하는 이외에, 우리는 반복 블록에서 핵심 요소를 취할 필요가 있음을 알 수 있습니다. 그것은 동일하거나 다를 수 있습니다.

<M> 
    <a> 
     <b> 
     <c f="123"> 
      <key>Al</key> 
      <key>Al</key> 
      <e NO="678"> 
       <f>Y</f> 
       <g> 
        <h>FTO</h> 
       </g> 
      </e> 
     </c> 
     </b> 
    </a> 
    <a> 
     <b> 
     <c f="567"> 
      <key>Al</key> 
      <e NO="678"> 
       <f>Y</f> 
       <g> 
        <h>FTO</h> 
       </g> 
      </e> 
     </c> 
     </b> 
    </a> 
    <a> 
     <b> 
     <somethingelse/> 
     </b> 
    </a> 
</M> 

답변

1

이 변환 :

012 :

<M> 
    <a> 
     <b> 
      <c f="123"> 
       <key>Al</key> 
       <e NO="678"> 
        <f>Y</f> 
        <g> 
         <h>FTO</h> 
        </g> 
       </e> 
      </c> 
     </b> 
    </a> 
    <a> 
     <b> 
      <c f="123"> 
       <key>Al</key> 
       <e NO="678"> 
        <f>Y</f> 
        <g> 
         <h>FTO</h> 
        </g> 
       </e> 
      </c> 
     </b> 
    </a> 
    <a> 
     <b> 
      <c f="567"> 
       <key>Al</key> 
       <e NO="678"> 
        <f>Y</f> 
        <g> 
         <h>FTO</h> 
        </g> 
       </e> 
      </c> 
     </b> 
    </a> 
    <a> 
     <b> 
      <somethingelse/> 
     </b> 
    </a> 
</M> 

가 원하는 정확한 결과 생산 : 제공된 XML 문서 적용

<xsl:stylesheet version="1.0" 
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
     <xsl:output omit-xml-declaration="yes" indent="yes"/> 
     <xsl:strip-space elements="*"/> 

     <xsl:key name="kAByC-F" match="a" use="*/c/@f"/> 

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

     <xsl:template match= 
      "a[*/c 
      and 
      not(generate-id() 
       = 
       generate-id(key('kAByC-F', */c/@f)[1]) 
       ) 
      ]"/> 

     <xsl:template match="a/b/c[@f]"> 
      <c f="{@f}"> 
      <xsl:apply-templates select="key('kAByC-F', @f)/b/c/key"/> 
      <xsl:apply-templates select="*[not(self::key)]"/> 
      </c> 
     </xsl:template> 
</xsl:stylesheet> 

3,516,

<M> <a> <b> <c f="123"> <key>Al</key> <key>Al</key> <e NO="678"> <f>Y</f> <g> <h>FTO</h> </g> </e> </c> </b> </a> <a> <b> <c f="567"> <key>Al</key> <e NO="678"> <f>Y</f> <g> <h>FTO</h> </g> </e> </c> </b> </a> <a> <b> <somethingelse/> </b> </a> </M> 

설명 :

  1. identity rule 사본을 "있는 그대로"모든 노드. 특정 노드와 일치하는 두 개의 템플릿으로 대체됩니다.

  2. 제 겹쳐 템플릿 키 (Muenchian grouping method)을 이용하여 지정된 제 a 소자 a되지 않은 모든 요소를 ​​삭제한다.

  3. 두 번째 덮어 쓰기 템플리트는 삭제되지 않은 (첫 번째 덮어 쓰기 템플리트에 의해) a 요소의 c 손자와 일치하고 처리합니다.

+0

최고. Dimitre에게 감사드립니다. 나는 여전히 흐름을 undertsnd 라인을 디버깅입니다. – Suresh

+0

@ 수레 : 환영합니다. 나는 그 질문을 설명으로 갱신했다. –