2014-12-10 1 views
1

요소의 중첩을 기반으로하는 시퀀스 번호가 필요합니다. 아래 예제에서 어떤 참조 요소의 자식이 아닌 모든 참조 요소는 시퀀스 번호를 가지며, 중첩 된 참조 요소는 부모 시퀀스 번호 + 현재 참조 요소의 십진수 + 위치를 가져야합니다.요소의 중첩을 기반으로하는 시퀀스 번호가 필요합니다.

Input.xml

<root> 
     <front> 
      <reference1 type="ref" href="a.xml"> 
       <reference1 type="ref" href="x.xml"/> 
       <reference1 type="ref" href="z.xml"/> 
      </reference> 
     </front> 
     <reference2 type="ref" href="b.xml"/> 
     <reference2 type="ref" href="c.xml"> 
      <reference2 type="ref" href="d.xml"> 
       <reference2 type="ref" href="y.xml"/> 
      </reference> 
     </reference> 
     <back> 
      <reference3 type="ref" href="e.xml"/> 
     </back> 
    </root> 

Output.xml

나는이 시도하지만 논리 얻을 수 있지 않다
<root> 
     <reference href="a.xml" sequence="1"/> 
     <reference href="x.xml" sequence="1.1"/> 
     <reference href="z.xml" sequence="1.2"/> 
     <reference href="b.xml" sequence="2"/> 
     <reference href="c.xml" sequence="3"/> 
     <reference href="d.xml" sequence="3.1"/> 
     <reference href="y.xml" sequence="3.1.1"/> 
     <reference href="e.xml" sequence="4"/> 
    </root> 

:

  <xsl:template match="/"> 
      <root> 
       <xsl:for-each select="//reference"> 
        <reference> 
           <xsl:attribute name="href"> 
            <xsl:value-of select="@href"/> 
           </xsl:attribute> 
         <xsl:if test="not(child::reference)"> 
           <xsl:attribute name="sequence"> 
            <xsl:value-of select="position()"/> 
           </xsl:attribute> 
         </xsl:if> 
         <xsl:if test="child::reference"> 
          <!-- something to be done here --> 
         </xsl:if> 
        </reference>  
       </xsl:for-each> 
      </root> 

감사를

답변

1

나의 제안을 사용하는 것입니다.당신을 위해 계산합니다. 개수가 정확하도록하려면 요소를 reference 개까지 좁혀 야합니다. 내가 틀렸을 수도 있고 쉬운 방법이있을 수도 있지만, 이것에 쓰는 데 몇 분 밖에 걸리지 않았습니다.

예를 들어, 수정 된 템플릿을 사용하여 정리 된 결과를 변수에 할당했습니다. 그런 다음 템플릿을 해당 변수에 적용하여 실제 변환을 수행합니다.

이것은 XSLT 2.0에서만 작동하지만 2.0 질문에 태그를 추가 했으므로 괜찮을 것입니다.

XML 입력

<root> 
    <front> 
     <reference href="a.xml"> 
      <reference href="x.xml"/> 
      <reference href="z.xml"/> 
     </reference> 
    </front> 
    <reference href="b.xml"/> 
    <foo/> 
    <reference href="c.xml"> 
     <reference href="d.xml"> 
      <foo> 
       <reference href="y.xml"/>     
      </foo> 
     </reference> 
    </reference> 
    <back> 
     <reference href="e.xml"/> 
    </back> 
</root> 

XSLT 2.0

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

    <xsl:variable name="refs"> 
     <refs> 
      <xsl:apply-templates select="/*//reference[not(ancestor::reference)]" mode="clean"/>     
     </refs> 
    </xsl:variable> 

    <xsl:template match="/root"> 
     <xsl:copy> 
      <xsl:apply-templates select="$refs"/>    
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="reference"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:attribute name="x"> 
       <xsl:number level="multiple"/> 
      </xsl:attribute> 
     </xsl:copy> 
     <xsl:apply-templates/> 
    </xsl:template> 

    <xsl:template match="reference" mode="clean"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates select=".//reference[ancestor::reference[1] is current()]" mode="clean"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

XML 출력

<root> 
    <reference href="a.xml" x="1"/> 
    <reference href="x.xml" x="1.1"/> 
    <reference href="z.xml" x="1.2"/> 
    <reference href="b.xml" x="2"/> 
    <reference href="c.xml" x="3"/> 
    <reference href="d.xml" x="3.1"/> 
    <reference href="y.xml" x="3.1.1"/> 
    <reference href="e.xml" x="4"/> 
</root> 
(테스트 <foo/> 요소의 몇 가지를 추가)

수정

다음은 질문의 업데이트 된 입력에 대한 업데이트 된 스타일 시트입니다. reference*[@type='ref']으로 변경하고 count 속성을 xsl:number에 추가하면됩니다.

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

    <xsl:variable name="refs"> 
     <refs> 
      <xsl:apply-templates select="/*//*[@type='ref'][not(ancestor::*[@type='ref'])]" mode="clean"/>     
     </refs> 
    </xsl:variable> 

    <xsl:template match="/root"> 
     <xsl:copy> 
      <xsl:apply-templates select="$refs"/>    
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="*[@type='ref']"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:attribute name="x"> 
       <xsl:number count="*[@type='ref']" level="multiple"/> 
      </xsl:attribute> 
     </xsl:copy> 
     <xsl:apply-templates/> 
    </xsl:template> 

    <xsl:template match="*[@type='ref']" mode="clean"> 
     <xsl:copy> 
      <xsl:copy-of select="@*"/> 
      <xsl:apply-templates select=".//*[@type='ref'][ancestor::*[@type='ref'][1] is current()]" mode="clean"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

솔루션을 이용해 주셔서 감사합니다. 귀하의 로직은 이전 소스에 대해 완벽하게 작동합니다. 이제 소스를 편집했습니다.이 새로운 시나리오에서는 노드 이름이 항상 같지는 않지만 유형 att는 동일합니다. 논리를 적용하면 xsl : number가 새로운 참조 요소마다 처음부터 시작되지만 동일한 출력이 필요합니다. 당신이 도울 수 있기를 바랍니다. 감사. – Namrata

+0

@Namrata - 업데이트 된 스타일 시트를 보려면 제 편집을 참조하십시오. –

+0

Daniel에게 감사드립니다. – Namrata