我需要一些关于这个XSLT的帮助。它正在按照它的方式工作,但是我已经改变了要求... :-)而且我需要修改它以给我预期的输出。 我正在寻找一些指导和帮助。
说明: 我有像这样的源码xml
<XML>
<Attributes>
<Attribute>
<Name/>
<Type/>
<Value/>
<FromIM/>
<collection/>
<Path />
</Attribute>
</Attributes>
</XML>
在上面的xml中,我需要查看节点“Type”并按类型对它们进行分组。例如,如果我有5个属性,其中Type是常见的,4个属性,其中Type是category,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>
从上面可以看出,我是第一组共同的&amp;类别并为常见的Complex创建一个组集合。这工作正常(虽然我正在使用Iteration ......: - ))
问题是我只为1个属性创建了一个Complex,其中Name = Collection并且它是硬编码的。但是,新要求是我为另一个属性创建了一个复杂的集合,其中name = Cost。
这是我遇到问题的地方。我怎样才能做到这一点。下面是示例源和输出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个收集节点,我需要输入当前日期。 注意在Collection Node中我可以有多个Complex节点。但是,在Cost中,我只有1个Complex节点。
<?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 :根据Michael的评论更新
<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>
答案 0 :(得分:0)
虽然远非完美,但这里有一个样式表可以产生你想要的输出。我不确定修复每个复杂的属性或修复集合的程度。如果这有帮助,请告诉我。
<?xml version="1.0"?>
<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']/Value"/>
<xsl:variable name="deptName" select="XML/Attributes/Attribute[Name='DepartmentName']/Value"/>
<xsl:variable name="groupName" select="XML/Attributes/Attribute[Name='GroupName']/Value"/>
<xsl:variable name="catPath" select="concat($familyName,'//',$deptName,'//',$groupName)" />
<xsl:attribute name="categorypath">
<xsl:value-of select="$catPath"/>
</xsl:attribute>
<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" mode="Collection">
<Collection id="" name='Collection'>
<xsl:apply-templates select="../Attribute[Name='Collection']" mode="Coll"/>
</Collection>
<Collection id="" name='Cost'>
<xsl:apply-templates select="../Attribute[Name='Cost']" mode="Cost"/>
</Collection>
</xsl:template>
<xsl:template match="Attribute[Type='Complex']"/>
<xsl:template match="Attribute[Type != 'Complex']">
<Attributes type="{Type}">
<xsl:variable name="Type" select="Type"/>
<xsl:apply-templates select="../Attribute[Type=$Type]" mode="Attr"/>
<xsl:if test="Type='common'">
<xsl:apply-templates select="." mode="Collection"/>
</xsl:if>
</Attributes>
</xsl:template>
<xsl:template match="Attribute" mode="Coll">
<xsl:apply-templates select="../Attribute[Name='UPC']" mode="UPC"/>
</xsl:template>
<xsl:template match="Attribute" mode="Cost">
<complex>
<Attr name="Cost" value="{../Attribute[Name='Cost']/Value}" valueKey="0"/>
<Attr name="Date" value="" valueKey="0"/>
</complex>
</xsl:template>
<xsl:template match="Attribute" mode="Attr">
<Attr name="{Name}" value="{Value}" valueKey="0"/>
</xsl:template>
<xsl:template match="Attribute" mode="UPC">
<complex>
<Attr name="UPC" value="{Value}" valueKey="0"/>
<Attr name="Color" value="{following::node()[Name='Color']/Value}" valueKey="0"/>
<Attr name="Size" value="{following::node()[Name='Size']/Value}" valueKey="0"/>
<Attr name="Style" value="{following::node()[Name='Style']/Value}" valueKey="0"/>
</complex>
</xsl:template>
</xsl:stylesheet>