2011-03-22 4 views
2

변환하는 동안 하나의 노드를 다른 노드로 결합 할 수있는 사람. 예를 들어, Attributes/Attribute/Type = ComplexAttr 일 때 Attributes/Attribute/Type = Common에만 있어야합니다. 다음은 사용하려는 XML & XSLT 샘플이 작동하지 않는 것입니다. TIA (미리 감사드립니다)XSLT 속성 값이 다른 경우 노드 결합

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="type" match="Attribute" use="Type"/> 
    <xsl:template match="/"> 
     <Data Schema="XML A"> 
      <xsl:apply-templates select="XML/Attributes/Attribute"> 
       <xsl:sort select="Type" order="descending"/> 
      </xsl:apply-templates> 
      <errorCodes> 
       <xsl:apply-templates select="XML/Attributes/Attribute" 
            mode="errors"/> 
      </errorCodes> 
     </Data> 
    </xsl:template> 
    <xsl:template 
      match="Attribute[generate-id()=generate-id(key('type', Type)[1])]"> 
     <xsl:if test="Type != 'ComplexAttr'"> 
      <Attributes type="{Type}"> 
       <xsl:if test="Type = 'ComplexAttr'"> 
        <xsl:value-of select="Common"/> 
       </xsl:if> 
       <xsl:apply-templates select="../Attribute[Type=current()/Type]" mode="out"/> 
      </Attributes>   
     </xsl:if> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="out"> 
     <Attr id="{id}" name="{Name}" value="{Value}"/> 
    </xsl:template> 
    <xsl:template match="Attribute"/> 
    <xsl:template match="Attribute" mode="errors"/> 
    <xsl:template match="Attribute[Value='']" mode="errors"> 
     <errorCode>"value for <xsl:value-of select="Name"/> is missing."</errorCode> 
    </xsl:template> 
    <xsl:template match="/Attribute"> 
     <xsl:if test="Type = 'ComplexAttr'"> 
      <Attributes type="Common"> 
       <xsl:apply-templates select="../Attribute[Type=current()/Type]" mode="out"/> 
       <!--<Attr id="{id}" name="{Name}" value="{Value}"/>--> 
      </Attributes> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

---- 원본 XML ---- 당신이 그룹 Attribute하려는 경우

<?xml version="1.0" encoding="windows-1252"?> 
<XML> 
    <Attributes> 
     <Attribute> 
      <id>5</id> 
      <Name>Buyer ID</Name> 
      <Type>common</Type> 
      <Value>Lee</Value> 
     </Attribute> 
     <Attribute> 
      <id>331</id> 
      <Name>Enviornment</Name> 
      <Type>common</Type> 
      <Value>Development</Value> 
     </Attribute> 
     <Attribute> 
      <id>79</id> 
      <Name>Retail</Name> 
      <Type>common</Type> 
      <Value></Value> 
     </Attribute> 
     <Attribute> 
      <id>402</id> 
      <Name>Gender</Name> 
      <Type>category</Type> 
      <Value>Men</Value> 
     </Attribute> 
    <Attribute> 
     <id>1197</id> 
     <Name>UPC</Name> 
     <Type>ComplexAttr</Type> 
     <Value>Testing</Value> 
     <Path /> 
    </Attribute> 
    </Attributes> 
</XML> 

---- 변환 된 XML 출력

<?xml version="1.0" encoding="utf-8"?> 
<Data Schema="XML A"> 
    <Attributes type="common"> 
    <Attr id="5" name="Buyer ID" value="Lee" /> 
    <Attr id="331" name="Enviornment" value="Development" /> 
    <Attr id="79" name="Retail" value="" /> 
    <Attr id="41" name="PlusShip" value="False" /> 
    <Collection id="" name="test"> 
     <ComplexAttr refId="0"> 
     <MaskValue /> 
     <Attr id="1197" name="UPC" value="Testing" /> 
     </ComplexAttr> 
    </Collection> 
    </Attributes> 
    <Attributes type="category"> 
    <Attr id="402" name="Gender" value="Men" /> 
    <Attr id="433" name="HeelHeight" value="" /> 
    </Attributes> 
    <errorCodes> 
    <errorCode>"value for Retail is missing."</errorCode> 
    </errorCodes> 
</Data> 

답변

4

같은 그룹에 Type'common''ComplexAttr'을 입력하면 키 값 표현식을 다음과 같이 변경해야합니다.

적용 및 그룹 템플릿 : (210)
<xsl:key name="type" 
     match="Attribute" 
     use="concat(
       Type[. != 'ComplexAttr'], 
       substring(
        'common', 
        1 div (Type = 'ComplexAttr') 
       ) 
      )"/> 

<xsl:template match="Attribute[ 
         generate-id() 
         = generate-id(
           key('type', 
            concat(
            Type[. != 'ComplexAttr'], 
            substring(
             'common', 
             1 div (Type = 'ComplexAttr') 
            ) 
           ) 
          )[1] 
          ) 
        ]">  

편집

<xsl:apply-templates select="key('type', 
           concat(
            Type[. != 'ComplexAttr'], 
            substring(
             'common', 
             1 div (Type = 'ComplexAttr') 
            ) 
           ) 
          )" 
        mode="out"/> 

편집 : 전체 예. 이 스타일은 :

<!DOCTYPE xsl:stylesheet [ 
<!ENTITY key "concat(Type[. != 'ComplexAttr'],substring('common',1 div (Type = 'ComplexAttr')))"> 
]> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="type" match="Attribute" use="&key;"/> 
    <xsl:template match="/"> 
     <Data Schema="XML A"> 
      <xsl:apply-templates 
       select="XML/Attributes/Attribute[ 
          generate-id() = generate-id(key('type', &key;)[1]) 
         ]"> 
       <xsl:sort select="&key;" order="descending"/> 
      </xsl:apply-templates> 
      <errorCodes> 
       <xsl:apply-templates select="XML/Attributes/Attribute" 
            mode="errors"/> 
      </errorCodes> 
     </Data> 
    </xsl:template> 
    <xsl:template match="Attribute"> 
     <xsl:variable name="vCurrent-Grouping-Key" select="&key;"/> 
     <Attributes type="{$vCurrent-Grouping-Key}"> 
      <xsl:apply-templates select="key('type',$vCurrent-Grouping-Key)" 
           mode="out"/> 
     </Attributes> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="out" name="makeAttr"> 
     <Attr id="{id}" name="{Name}" value="{Value}"/> 
    </xsl:template> 
    <xsl:template match="Attribute[Type='ComplexAttr']" mode="out"> 
     <Collection id="" name="test"> 
      <ComplexAttr refId="0"> 
       <MaskValue /> 
       <xsl:call-template name="makeAttr"/> 
      </ComplexAttr> 
     </Collection> 
    </xsl:template> 
    <xsl:template match="Attribute" mode="errors"/> 
    <xsl:template match="Attribute[Value='']" mode="errors"> 
     <errorCode>"value for <xsl:value-of select="Name"/> is missing."</errorCode> 
    </xsl:template> 
</xsl:stylesheet> 

출력 :

<Data Schema="XML A"> 
    <Attributes type="common"> 
     <Attr id="5" name="Buyer ID" value="Lee" /> 
     <Attr id="331" name="Enviornment" value="Development" /> 
     <Attr id="79" name="Retail" value="" /> 
     <Collection id="" name="test"> 
      <ComplexAttr refId="0"> 
       <MaskValue /> 
       <Attr id="1197" name="UPC" value="Testing" /> 
      </ComplexAttr> 
     </Collection> 
    </Attributes> 
    <Attributes type="category"> 
     <Attr id="402" name="Gender" value="Men" /> 
    </Attributes> 
    <errorCodes> 
     <errorCode>"value for Retail is missing."</errorCode> 
    </errorCodes> 
</Data> 
+0

나는 그것을 시도 @Alejandro. 그러나 나는 복사본을 포함하는 추가 노드를 얻고 있습니다. 열쇠의 가치를 어떻게 찾을 수 있습니까? Visual Studio 2005를 사용하고 있습니다. – JohnXsl

+1

@ JohnXsl : 이해가 안됩니다. 전체 답변을 보려면 업데이트를 확인하십시오. –

+0

+1은 _provided_ 정의에 대한 정답입니다. – Flack