我需要一些关于此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