我需要一些關於此XSLT的幫助。它的工作方式是假設我的需求發生了變化... :-),並且我需要修改它來給我預期的輸出。 我正在尋找一些指導和幫助。帶有多個集合的XSLT分組
說明: 我有一個源XML這樣
<XML>
<Attributes>
<Attribute>
<Name/>
<Type/>
<Value/>
<FromIM/>
<collection/>
<Path />
</Attribute>
</Attributes>
</XML>
在上述XML我需要看節點「類型」,並將它們組由類型。例如,如果我有5個屬性,其中Type是常見的,4個屬性(其中Type是類別),以及3個屬性(其中Type是Complex),則將它們按照這種方式分組。
<?xml version="1.0" encoding="utf-8"?>
<Data Schema="XML A">
<Items>
<Item id="" shortname="FT123" longname="FT123" categorypath="FamilyName//DepartmentName//GroupName" type="Product">
<Attributes type="common">
<Attr name="common 1" value="1" path=""/>
<Attr name="common 2" value="2" path=""/>
<Attr name="common 3" value="3" path=""/>
<Attr name="common 4" value="4" path=""/>
<Attr name="common 5" value="4" path=""/>
<Collection id="" name="Collection" path="">
<Complex>
<Attr name="UPC" value="Testing" valueKey="0" />
<Attr name="Color" value="Yellow" valueKey="0"/>
<Attr name="Size" value="10" valueKey="0"/>
</Complex>
</Collection>
</Attributes>
<Attributes type="category">
<Attr name="category1" value="1" />
<Attr name="category2" value="2" />
<Attr name="category3" value="3" />
<Attr name="category4" value="4" />
</Attributes>
</Item>
</Items>
</Data>
正如你可以從上面看到我組第一共用&類別和創造下常見的複雜的一組集合。這工作正常(雖然我使用迭代... :-))
問題是我創建一個複雜的只有一個屬性,其中名稱=集合,它是硬編碼。但是,新的要求是我爲名稱=成本的另一個屬性創建了一個複雜的集合。
這是我遇到問題的地方。我怎樣才能做到這一點。以下是示例源代碼和輸出xml和XSLT。提前致謝。
源XML:
<?xml version="1.0" encoding="Windows-1252"?>
<XML>
<Attributes>
<Attribute>
<Name>FamilyName</Name>
<Type>common</Type>
<Value>Footwear</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>DepartmentName</Name>
<Type>common</Type>
<Value>Footwear</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>GroupName</Name>
<Type>common</Type>
<Value>Men's Boots</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Buyer ID</Name>
<Type>common</Type>
<Value>Lee</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Enviornment</Name>
<Type>common</Type>
<Value>Dev</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Retail</Name>
<Type>common</Type>
<Value></Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Gender</Name>
<Type>category</Type>
<Value>M</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Cost</Name>
<Type>Complex</Type>
<Value>20.00</Value>
<FromIM>yes</FromIM>
<collection>Y</collection>
<Path />
</Attribute>
<Attribute>
<Name>Collection</Name>
<Type>Complex</Type>
<Value>ing</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>UPC</Name>
<Type>Complex</Type>
<Value>Testing</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Color</Name>
<Type>Complex</Type>
<Value>Yellow</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Size</Name>
<Type>Complex</Type>
<Value>10</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Style</Name>
<Type>Complex</Type>
<Value>MA</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>UPC</Name>
<Type>Complex</Type>
<Value>24a</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Color</Name>
<Type>Complex</Type>
<Value>Green</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Size</Name>
<Type>Complex</Type>
<Value>22</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
<Attribute>
<Name>Style</Name>
<Type>Complex</Type>
<Value>AM</Value>
<FromIM>no</FromIM>
<collection>N</collection>
<Path />
</Attribute>
</Attributes>
</XML>
預期輸出: 我需要2個集節點也日期我需要把當前的日期。 收集節點中的注意事項我可以有多個複雜節點。但是,在成本中,我將只有1個複雜節點。
<?xml version="1.0" encoding="utf-8"?>
<Data Schema="XML A">
<Items>
<Item id="" shortname="FT123" longname="FT123" sku="FT123" action="ADD" categorypath="FamilyName//DepartmentName//GroupName" type="Product">
<Attributes type="common">
<Attr name="Buyer ID" value="Lee" path="" action="ADD" />
<Attr name="Enviornment" value="Dev" path="" action="ADD" />
<Attr name="Retail" value="" path="" action="ADD" />
<Collection id="" name="Collection" path="">
<Complex>
<Attr name="UPC" value="Testing" valueKey="0" />
<Attr name="Color" value="Yellow" valueKey="0"/>
<Attr name="Size" value="10" valueKey="0"/>
<Attr name="Style" value="MA" valueKey="0"/>
</Complex>
<Complex>
<Attr name="UPC" value="24a" valueKey="0"/>
<Attr name="Color" value="Green" valueKey="0"/>
<Attr name="Size" value="22" valueKey="0"/>
<Attr name="Style" value="AM" valueKey="0"/>
</Complex>
</Collection>
<Collection id="" name="Cost" path="">
<Complex>
<Attr name="Cost" value="22" valueKey="0" />
<Attr name="Date" value="" valueKey="0"/>
</Complex>
</Collection>
</Attributes>
<Attributes type="category">
<Attr name="Gender" value="M" />
</Attributes>
</Item>
</Items>
</Data>
XSLT:根據邁克爾的評論
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="type" match="Attribute" use="Type"/>
<xsl:template match="/">
<Data Schema="XML A">
<Items>
<Item>
<xsl:variable name="fileName" select="XML/Attributes/Attribute[Name = 'PIFileNumber']/Value"/>
<xsl:attribute name="id"></xsl:attribute>
<xsl:attribute name="shortname">
<xsl:value-of select="$fileName"/>
</xsl:attribute>
<xsl:attribute name="longname">
<xsl:value-of select="$fileName"/>
</xsl:attribute>
<xsl:variable name="familyName" select="XML/Attributes/Attribute[Name = 'FamilyName'/id"/>
<xsl:variable name="deptName" select="XML/Attributes/Attribute[Name = 'DepartmentName']/id"/>
<xsl:variable name="groupName" select="XML/Attributes/Attribute[Name = 'GroupName']/id"/>
<xsl:variable name="catPath" select="concat($familyName,'//',$deptName,'//',$groupName)" />
<xsl:attribute name="categorypath" select="$catPath"/>
<xsl:attribute name="type">Product</xsl:attribute>
<xsl:apply-templates select="XML/Attributes/Attribute[generate-id() = generate-id(key('type', Type)[1])]">
<xsl:sort select="Type" order="descending"/>
</xsl:apply-templates>
</Item>
</Items>
</Data>
</xsl:template>
<xsl:template match="Attribute">
<xsl:variable name="compType" select="count(/XML/Attributes/Attribute[Type='Complex' and Name!='Collection'])"/>
<xsl:variable name="colid" select="/XML/Attributes/Attribute[Name = 'Collection']/id"/>
<xsl:variable name="colname" select="/XML/Attributes/Attribute[Name = 'Collection']/Name"/>
<xsl:variable name="colpath" select="/XML/Attributes/Attribute[Name = 'Collection']/Path"/>
<xsl:if test="Type!='Complex'">
<Attributes type="{Type}">
<xsl:apply-templates select="key('type',Type)" mode="out"/>
<xsl:if test="Type='common'">
<Collection id="{$colid}" name="{$colname}" path="{$colpath}" action="ADD">
<xsl:choose>
<xsl:when test="$compType > 0">
<xsl:call-template name="for.loop">
<xsl:with-param name="i">1</xsl:with-param>
<xsl:with-param name="count" select="count(/XML/Attributes/Attribute[Type='Complex' and Name='UPC'])" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<Complex refId="0">
<MaskValue />
<Attr id="" name="UPC" value="" valueKey="0"/>
<xsl:choose>
<xsl:when test="count(/XML/Attributes/Attribute[Name = 'Color']) > 0">
<Attr id="{//Attribute[Name = 'Color']/id}" name="Color" value="{//Attribute[Name = 'Color']/Value}" valueKey="0"/>
</xsl:when>
<xsl:otherwise>
<Attr id="" name="Color" value="Default" valueKey="0"/>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="count(/XML/Attributes/Attribute[Name = 'Size']) > 0">
<Attr id="{//Attribute[Name = 'Size']/id}" name="Color" value="{//Attribute[Name = 'Size']/Value}" valueKey="0"/>
</xsl:when>
<xsl:otherwise>
<Attr id="" name="Size" value="Default" valueKey="0"/>
</xsl:otherwise>
</xsl:choose>
<Attr id="" name="Style" value="" valueKey="0"/>
<Attr id="" name="Exclude" value="0" valueKey="0"/>
</Complex>
</xsl:otherwise>
</xsl:choose>
</Collection>
</xsl:if>
</Attributes>
</xsl:if>
</xsl:template>
<xsl:template match="Attribute" mode="out">
<xsl:if test="FromIM = 'yes'">
<xsl:choose>
<xsl:when test="collection = 'Y' and Name!='Color' and Name!='Size'">
<Collection id="" name="{Name}" path="{Path}">
<Attr value="{Value}" uom="" locale="en_WW"/>
</Collection>
</xsl:when>
<xsl:otherwise>
<xsl:if test="Name!='FileNumber' and Name!='NotReqInIM' and Name!='Color' and Name!='Size'">
<Attr id="{id}" name="{Name}" value="{Value}" path="{Path}" action="ADD" uom="" Locale="en_WW"/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<xsl:template match="Attribute[Type='Complex']" mode="out">
<xsl:if test="Name!='Collection'">
<Attr id="{id}" name="{Name}" value="{Value}" valueKey="0"/>
</xsl:if>
</xsl:template>
<!-- this is for loop code -->
<xsl:template name="for.loop">
<xsl:param name="i" />
<xsl:param name="count" />
<!--begin_: Line_by_Line_Output -->
<xsl:if test="$i <= $count">
<xsl:if test="Name!='Collection'">
<Complex refId="0">
<MaskValue />
<Attr id="{(//Attribute[Type='Complex' and Name = 'UPC'])[position() = $i]/id}" name="UPC" value="{(//Attribute[Type='Complex' and Name = 'UPC'])[position() = $i]/Value}" valueKey="0"/>
<Attr id="{(//Attribute[Type='Complex' and Name = 'Color'])[position() = $i]/id}" name="Color" value="{(//Attribute[Type='Complex' and Name = 'Color'])[position() = $i]/Value}" valueKey="0"/>
<Attr id="{(//Attribute[Type='Complex' and Name = 'Size'])[position() = $i]/id}" name="Size" value="{(//Attribute[Type='Complex' and Name = 'Size'])[position() = $i]/Value}" valueKey="0"/>
<Attr id="{(//Attribute[Type='Complex' and Name = 'Style'])[position() = $i]/id}" name="Style" value="{(//Attribute[Type='Complex' and Name = 'Style'])[position() = $i]/Value}" valueKey="0"/>
<Attr id="0" name="Exclude" value="0" valueKey="0"/>
</Complex>
</xsl:if>
</xsl:if>
<!--begin_: RepeatTheLoopUntilFinished-->
<xsl:if test="$i <= $count">
<xsl:call-template name="for.loop">
<xsl:with-param name="i">
<xsl:value-of select="$i + 1"/>
</xsl:with-param>
<xsl:with-param name="count">
<xsl:value-of select="$count"/>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
您的代碼會更容易閱讀'<集合名稱= 「{NAME}」 路徑= 「{PATH}」/>'。在一些變量中有很多不必要的冗長,例如您可以將colname初始化爲 ' –
2011-04-21 09:26:29
@Michael。感謝您的答覆。根據您對變量初始化的評論,我修改了XSLT。但是,我不明白你的意思是使用屬性值模板。你能解釋一下嗎?謝謝 – JohnXsl 2011-04-21 14:04:07