2011-04-12 5 views
0

녀석, 그룹화 된 재귀가 작동하지 않습니다. XSLT 1.0을 사용하고 있습니다. 이것을 이해하려면 도움이 필요합니다. 미리 감사드립니다.XSLT 그룹화 재귀 문제

배경 : 나는 XML의 3 개 가지 유형 (일반, 카테고리, & 복합)가 있습니다. 내 목표는.

1 - 유형 기반 xml 노드 그룹화. 2 - Type = common 아래에서 complex에 대한 하위 그룹을 만듭니다. 3 - Type = complex의 경우 소스 xml에 따라 많은 수의 콜렉션을 작성하십시오. 각 컬렉션에는 Name = 'A'또는 'B'또는 'C'또는 'D'인 4 개의 요소 만 나열되어야합니다. 여기가 문제가되는 곳입니다. 그룹화 및 하위 그룹화가 올바르게 작동합니다. 그러나 재귀를 사용하여 컬렉션을 만들려고 할 때 의도 한 결과를 얻지 못합니다. 참조를 위해 예상되는 xml 샘플을 참조하십시오.

소스 XML :

<?xml version="1.0" encoding="Windows-1252"?> 
<XML> 
    <Attributes> 
    <Attribute> 
     <Name>Buyer ID</Name> 
     <Type>common</Type> 
     <Value>Lee</Value> 
    </Attribute> 
    <Attribute> 
     <Name>Enviornment</Name> 
     <Type>common</Type> 
     <Value>Dev</Value> 
    </Attribute> 
    <Attribute> 
     <Name>Retail</Name> 
     <Type>common</Type> 
     <Value></Value> 
    </Attribute> 
    <Attribute> 
     <Name>Gender</Name> 
     <Type>category</Type> 
     <Value>M</Value> 
    </Attribute> 
    <Attribute> 
     <Name>Collection</Name> 
     <Type>Complex</Type> 
     <Value>ing</Value> 
     <Path /> 
    </Attribute> 
    <Attribute> 
     <Name>A</Name> 
     <Type>Complex</Type> 
     <Value>Testing</Value> 
     <Path /> 
    </Attribute> 
    <Attribute> 
     <Name>B</Name> 
     <Type>Complex</Type> 
     <Value>Yellow</Value> 
     <Path /> 
    </Attribute> 
    <Attribute> 
     <Name>C</Name> 
     <Type>Complex</Type> 
     <Value>10</Value> 
     <Path /> 
    </Attribute> 
    <Attribute> 
     <Name>D</Name> 
     <Type>Complex</Type> 
     <Value>MA</Value> 
     <Path /> 
    </Attribute> 
    <Attribute> 
     <Name>A</Name> 
     <Type>Complex</Type> 
     <Value>24a</Value> 
     <Path /> 
    </Attribute> 
    <Attribute> 
     <Name>B</Name> 
     <Type>Complex</Type> 
     <Value>Green</Value> 
     <Path /> 
    </Attribute> 
    <Attribute> 
     <Name>C</Name> 
     <Type>Complex</Type> 
     <Value>22</Value> 
     <Path /> 
    </Attribute> 
    <Attribute> 
     <Name>D</Name> 
     <Type>Complex</Type> 
     <Value>AM</Value> 
     <Path /> 
    </Attribute> 
    </Attributes> 
</XML> 

예상 출력 :

다음
<?xml version="1.0" encoding="utf-8"?> 
<Data Schema="XML A"> 
    <Items> 
    <Item> 
     <Attributes type="common"> 
     <Attr name="Buyer ID" value="Lee" /> 
     <Attr name="Enviornment" value="Dev" /> 
     <Attr name="Retail" value="" /> 
     <Collection name="Collection" > 
      <Complex> 
      <Attr name="A" value="Testing" /> 
      <Attr name="B" value="Yellow" /> 
      <Attr name="C" value="10" /> 
      <Attr name="D" value="MA" /> 
      </Complex> 
      <Complex> 
      <Attr name="A" value="24a" /> 
      <Attr name="B" value="Green" /> 
      <Attr name="C" value="22" /> 
      <Attr name="D" value="AM" /> 
      </Complex> 
     </Collection> 
     </Attributes> 
     <Attributes type="category"> 
     <Attr name="Gender" value="M" /> 
     </Attributes> 
     <errorCodes> 
     <errorCode>value for Retail is missing.</errorCode> 
     </errorCodes> 
    </Item> 
    </Items> 
</Data> 

는 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="type" match="Attribute" use="Type"/> 
    <xsl:variable name="group" select="4"/> 
    <xsl:template match="/"> 
     <Data Schema="XML A"> 
      <Items> 
       <Item> 
        <xsl:apply-templates select="XML/Attributes/Attribute[generate-id() = generate-id(key('type', Type)[1])]"> 
         <xsl:sort select="Type" order="descending"/> 
        </xsl:apply-templates> 
        <errorCodes> 
         <xsl:apply-templates select="XML/Attributes/Attribute" mode="errors"/> 
        </errorCodes> 
       </Item> 
      </Items> 
     </Data> 
    </xsl:template> 
    <xsl:template match="Attribute"> 
     <xsl:variable name="compType" select="count(/XML/Attributes/Attribute[Type='Complex' and Name!='Collection'])"/> 
     <xsl:if test="Type!='Complex'"> 
      <Attributes type="{Type}"> 
       <xsl:apply-templates select="key('type',Type)" mode="out"/> 
       <xsl:if test="Type='common'"> 
        <Collection> 
         <xsl:for-each select="/XML/Attributes/Attribute[Type='Complex']"> 
          <xsl:choose> 
           <xsl:when test="(Name='A' or Name='B' or Name='C' or Name='D')"> 
            <xsl:if test="(($compType > 0) and (Name!='Collection'))"> 
             <xsl:apply-templates select="key('type','Complex')" mode="out"/> 
            </xsl:if> 
           </xsl:when> 
           <xsl:otherwise> 
            <Complex> 
             <Attr id="" name="A" value="Default" /> 
             <Attr id="" name="B" value="Default" /> 
             <Attr id="" name="C" value="Default" /> 
             <Attr id="" name="D" value="" /> 
            </Complex> 
           </xsl:otherwise> 
          </xsl:choose> 
         </xsl:for-each> 
        </Collection> 
       </xsl:if> 
      </Attributes> 
     </xsl:if> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="out"> 
     <Collection> 
      <Attr name="{Name}" value="{Value}"/> 
     </Collection> 
    </xsl:template> 
    <xsl:template match="Attribute[Type='Complex']" mode="out"> 
     <xsl:apply-templates select="XML/Attributes/Attribute[not(Name='Collection')] 
               [position() mod $group = 1]" mode="group"/> 
    </xsl:template> 
    <xsl:template match="Name" mode="group"> 
     <xsl:if test="Name!='Collection'"> 
      <Attr name="{Name}" value="{Value}"/> 
     </xsl:if> 
    </xsl:template> 
    <xsl:template match="Attribute"> 
     <Complex> 
      <xsl:apply-templates 
       select=".|following-sibling::Attribute[position() &lt; $group]" mode="inner" /> 
     </Complex> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="errors"> 
     <xsl:if test="(Name='Retail' or Name='Product Description') and Value=''"> 
      <errorCode>value for <xsl:value-of select="Name"/> is missing.</errorCode> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

답변

0

나는 귀하의 모든 요구 사항을 이해 확실하지 오전하지만에게 있습니다 ~의 lowing 샘플

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:data="http://example.com/data" 
    exclude-result-prefixes="data" 
    version="1.0"> 

    <xsl:output indent="yes"/> 

    <xsl:key name="att-by-type" match="Attributes/Attribute" use="Type"/> 

    <xsl:variable name="complex" select="key('att-by-type', 'Complex')"/> 

    <xsl:template match="XML"> 
    <Data Schema="XML A"> 
     <Items> 
     <Item> 
      <xsl:apply-templates select="Attributes/Attribute[Type = 'common' or Type = 'category'][generate-id() = generate-id(key('att-by-type', Type)[1])]" mode="group"/> 
     </Item> 
     </Items> 
    </Data> 
    </xsl:template> 

    <xsl:template match="Attribute" mode="group"> 
    <Attributes type="{Type}"> 
     <xsl:apply-templates select="key('att-by-type', Type)"/> 
     <xsl:if test="Type = 'common'"> 
     <Collection name="Collection"> 
      <xsl:apply-templates select="$complex[Name = 'A']" mode="comp-group"/> 
     </Collection> 
     </xsl:if> 
    </Attributes> 
    </xsl:template> 

    <xsl:template match="Attribute" mode="comp-group"> 
    <Complex> 
     <xsl:variable name="pos" select="position()"/> 
     <xsl:apply-templates select="$complex[Name = 'A'][position() = $pos] | 
            $complex[Name = 'B'][position() = $pos] | 
            $complex[Name = 'C'][position() = $pos] | 
            $complex[Name = 'D'][position() = $pos]"/> 
    </Complex> 
    </xsl:template> 

    <xsl:template match="Attribute"> 
    <Attr name="{Name}" value="{Value}"/> 
    </xsl:template> 

</xsl:stylesheet> 

(이것은 다른 문제와 관련이없는 듯, 나는 그 밖으로 왼쪽 ErrorCode가를 제외하고) 당신이 게시 된 출력을 생성합니다.

+0

답변 해 주셔서 감사합니다. 그것은 작동하지만 내 코드로 구현하려고하면 작동하지 않았다. 내 게시물을 참조하십시오 http://stackoverflow.com/questions/5638460/xslt-grouping-recursive-problem-part-2 – JohnXsl