2012-07-10 2 views
1

나는이 입력하는 경우 :XSLT를 사용하여이 하위 요소를 함께 결합하는 방법은 무엇입니까?

<root> 
    <library id="L1"> 
     <shelf1 id="1"> 
      <book id="1" category="science"> 
       <attributes>      
        <year>2000</year> 
       </attributes> 
       <attributes> 
        <author>xx</author> 
        <year>2010</year> 
        <isbn>001</isbn> 
       </attributes> 
       <attributes> 
        <author>yy</author> 
        <publisher>zz</publisher> 
        <isbn>002</isbn> 
       </attributes> 
       <other>y</other> 
      </book> 
      <book id="2" category="science"> 
       ... 
      </book> 
     </shelf1> 

     <shelf2>...</shelf2> 
    </library> 
</root> 

expetced 출력 :

<root> 
    <library id="L1"> 
     <shelf1 id="1"> 
      <book id="1" category="science"> 
       <attributes> 
        <author>yy</author>      
        <publisher>zz</publisher> 
        <isbn>002</isbn> 
        <year>2010</year> 
       </attributes> 
       <other>y</other> 
      </book> 
      <book id="2" category="science"> 
       ... 
      </book> 
     </shelf1> 

     <shelf2>...</shelf2> 
    </library> 
</root> 

내가 함께 요소 '속성'을 결합해야합니다. 두 개 이상의 속성이 존재하는 경우, 이전에 속성의 하위가 존재하지 않았 으면 새 정보로 유지하지만 이전에 존재하면 단순히 최신 값을 사용합니다.

XSLT 1.0 또는 2.0에서 이러한 변환을 수행하는 방법은 도움이됩니다.

답변

2

이 변환 (XSLT 2.0) : 제공된 XML 문서에 적용

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

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

<xsl:template match="book[attributes]"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*"/> 
    <attributes> 
     <xsl:for-each-group select="attributes/*" group-by="name()"> 
     <xsl:sort select="current-grouping-key()"/> 
     <xsl:apply-templates select="."/> 
     </xsl:for-each-group> 
    </attributes> 
    <xsl:apply-templates select="*[not(self::attributes)]"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

:

<root> 
    <library id="L1"> 
     <shelf1 id="1"> 
      <book id="1" category="science"> 
       <attributes> 
        <year>2000</year> 
       </attributes> 
       <attributes> 
        <author>xx</author> 
        <year>2010</year> 
        <isbn>001</isbn> 
       </attributes> 
       <attributes> 
        <author>yy</author> 
        <publisher>zz</publisher> 
        <isbn>002</isbn> 
       </attributes> 
       <other>y</other> 
      </book> 
      <book id="2" category="science"> 
      ... 
      </book> 
     </shelf1> 
     <shelf2>...</shelf2> 
    </library> 
</root> 

이 원하는 정확한 결과를 생성 :

012 3,516,
<root> 
     <library id="L1"> 
      <shelf1 id="1"> 
        <book id="1" category="science"> 
      <attributes> 
       <author>xx</author> 
       <isbn>001</isbn> 
       <publisher>zz</publisher> 
       <year>2000</year> 
      </attributes> 
      <other>y</other> 
     </book> 
        <book id="2" category="science"> 
      ... 
      </book> 
      </shelf1> 
      <shelf2>...</shelf2> 
     </library> 
</root> 

설명 :

  1. 적절한 사용 및 신원 규칙의 최우선.

  2. group-by 인 XSLT 2.0 명령어 xsl:for-each-group을 올바르게 사용하십시오.

  3. XSLT 2.0 함수 current-grouping-key()과 XPath 함수 name()의 올바른 사용.

+0

깔끔하고 멋진 솔루션에 감사드립니다. – John

+0

@ 존, 오신 것을 환영합니다. –

관련 문제