2011-03-22 150 views
2

轉換期間,我可以將一個節點合併到另一個節點中。例如,當屬性/屬性/類型= ComplexAttr時,它應該在屬性/屬性/類型=僅公共屬性下。 下面是示例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 ----

<?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

如果你想組Attribute通過Type'common''ComplexAttr'在同一組中,那麼您需要將鍵值表達式更改爲如下形式:

<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] 
          ) 
        ]">  

EDIT:而在組模板施加:

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

EDIT:全例子。這個樣式表:

<!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 2011-03-22 22:22:18

+1

@JohnXsl:我不明白。檢查我的更新以獲得完整答案。 – 2011-03-22 22:50:58

+0

對於_provided_定義的正確答案+1。 – Flack 2011-03-23 10:35:35