2011-01-12 8 views
1

xslt를 사용하여 XML을 변환해야합니다.자식 요소 값 및 시퀀스 번호를 기반으로 부모 노드 그룹화

논리 :

분할 부모가 다른 자식 주소를 가진 부모 이름과 일련 번호를 추가하면 부모. 또한 아이에게 줄 번호가 필요합니다. 여기에는 부모 노드 수가 많으며 각 부모 노드에는 더 많은 자식 노드가있을 수 있습니다.

저는 이것을 달성하기 위해 여러 가지 방법을 시도했으며 foreach에서 일련 번호를 생성하는 데 어려움을 겪고 있습니다. 그래서 어느 누구도이 문제에 대한 해결책을 제시 할 수는 없습니다. 아래

원본 XML :

<Data> 
    <Parent> 
     <Name>P1</Name> 
     <Child> 
     <Name>CName1</Name> 
     <Address>Address1</Address> 
     </Child> 
     <Child> 
     <Name>CName2</Name> 
     <Address>Address2</Address> 
     </Child> 
     <Child> 
     <Name>CName3</Name> 
     <Address>Address1</Address> 
     </Child> 
    </Parent> 

    <Parent> 
    <Name>P2</Name> 
     <Child> 
     <Name>CName1</Name> 
     <Address>Address1</Address> 
     </Child> 
    </Parent> 
</Data> 

목표 XML은 아래와 같아야

<Data> 
    <Parent> 
    <Name>P1_1</Name> 
    <Address>Address1</Address> 
    <Child> 
     <LineNumber>1</LineNumber> 
     <Name>CName1</Name> 
    </Child> 
    <Child> 
     <LineNumber>2</LineNumber> 
     <Name>CName3</Name> 
    </Child> 
    </Parent> 

    <Parent> 
     <Name>P1_2</Name> 
     <Address>Address2</Address> 
     <Child> 
     <LineNumber>1</LineNumber> 
     <Name>CName2</Name> 
     </Child> 
    </Parent> 

    <Parent> 
     <Name>P2_1</Name> 
     <Address>Address1</Address> 
     <Child> 
      <LineNumber>1</LineNumber> 
      <Name>CName1</Name> 
     </Child> 
    </Parent> 
</Data> 
+0

{} 버튼을 사용하여 코드 형식을 지정하십시오. – bluish

+0

그룹화 문제를 해결하려면 XSLT 2.0을 사용할 수 있는지 또는 XSLT 1.0을 사용하는지 여부를 알려줘야합니다. * 2.0으로 그룹화 * 쉽습니다. 또한 문제의 일부분 (그룹화)을 해결하고 다른 부분 (번호 매기기)에 붙어 있다면 얼마나 멀리 있는지 알려주는 것이 좋습니다. 아주 작은 조정이 필요할 수도 있고 접근 방식이 완전히 완료되었을 수도 있습니다 잘못 인도했다. –

답변

3

이 XSLT 1.0 변환 :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:key name="kAddress" match="Child" use="concat(generate-id(..), '|', Address)" /> 

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

    <xsl:template match="Parent"> 
    <xsl:variable name="parent" select="." /> 
    <xsl:for-each select="Child[ 
     generate-id() 
     = 
     generate-id(key('kAddress', concat(generate-id($parent), '|', Address))[1]) 
    ]"> 
     <Parent> 
     <Name><xsl:value-of select="concat(../Name, '_', position())" /></Name> 
     <xsl:copy-of select="Address" /> 
     <xsl:apply-templates select=" 
      key('kAddress', concat(generate-id($parent), '|', Address)) 
     " /> 
     </Parent> 
    </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="Child"> 
    <xsl:copy> 
     <xsl:copy-of select="@*" /> 
     <LineNumber><xsl:value-of select="position()" /></LineNumber> 
     <xsl:apply-templates select="node()[not(self::Address)]" /> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

은 샘플에 대한 다음과 같은 출력을 생성 :

<Data> 
    <Parent> 
     <Name>P1_1</Name> 
     <Address>Address1</Address> 
     <Child> 
      <LineNumber>1</LineNumber> 
      <Name>CName1</Name> 
     </Child> 
     <Child> 
      <LineNumber>2</LineNumber> 
      <Name>CName3</Name> 
     </Child> 
    </Parent> 
    <Parent> 
     <Name>P1_2</Name> 
     <Address>Address2</Address> 
     <Child> 
      <LineNumber>1</LineNumber> 
      <Name>CName2</Name> 
     </Child> 
    </Parent> 
    <Parent> 
     <Name>P2_1</Name> 
     <Address>Address1</Address> 
     <Child> 
      <LineNumber>1</LineNumber> 
      <Name>CName1</Name> 
     </Child> 
    </Parent> 
</Data> 
+0

+1 정답입니다. –

+0

+1. 다 맞 앗어. – Flack

+0

+1 가독성을 위해 부모와 주소로 차일을 사용합니다. –

관련 문제