具有多组集合的 XSLT 分组

发布于 2024-11-03 00:43:20 字数 15716 浏览 0 评论 0原文

我需要一些有关此 XSLT 的帮助。它正在按照预期的方式工作,但是我的需求发生了变化......:-),我需要修改它以获得预期的输出。 我正在寻求一些指导和帮助。

解释: 我有一个像这样的源 xml

<XML>
  <Attributes>
    <Attribute>
    <Name/>
    <Type/>
    <Value/>
    <FromIM/>
    <collection/>
      <Path />
    </Attribute>
</Attributes>
</XML>

在上面的 xml 中,我需要查看节点“类型”并按类型对它们进行分组。例如,如果我有 5 个类型为常见的属性,4 个类型为类别的属性,以及 3 个类型为复杂的属性,则将它们分组如下。

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

正如你从上面看到的,我是小组第一普通人和第二人。类别并在 common 下为 Complex 创建一个组集合。这工作正常(尽管我正在使用迭代...:-))

问题是我只为 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 个集合节点,我需要输入当前日期。 请注意,在集合节点中,我可以有多个复杂节点。然而,在成本中我只有 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:根据 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 &lt;= $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 &lt;= $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>

I need some help with this XSLT. It is working the way it is suppose to however I have change in requirements ... :-) and I need to modify this to give me the expected output.
I'm looking for some guidance and help.

Explanation:
I have a source xml like this

<XML>
  <Attributes>
    <Attribute>
    <Name/>
    <Type/>
    <Value/>
    <FromIM/>
    <collection/>
      <Path />
    </Attribute>
</Attributes>
</XML>

In the above xml I need to look at the node "Type" and group them by the type. For example, if I have 5 attribute where Type is common, and 4 attributes where Type is category, and 3 attributes where Type is Complex then group them like this.

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

As you can see from above that I'm group first common & category and creating a group collection for Complex under common. This is working fine (Although I'm using Iteration ... :-))

The problem is I'm creating a Complex for only 1 attribute where Name = Collection and it is hard coded. However, the new requirement is that I have create a complex collection for another attribute where name=Cost.

This is where I'm having problem. How can I do this. Below are the sample source and output xml and XSLT. Thanks in Advance.

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

Expected Output:
I need 2 collection nodes also in date I need to put current date.
Note in the Collection Node I can have multiple Complex nodes. However, in the Cost I will have only 1 Complex node.

<?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: Updated based on Michael's comment

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笔落惊风雨 2024-11-10 00:43:20

虽然远非完美,但这里有一个样式表可以生成您想要的输出。我不确定每个复合体的属性或集合的固定程度。让我知道这是否有帮助。

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

Although far from perfect, here is one stylesheet that will produce the output you wanted. I'm not sure to what degree the attributes of each complex are fixed or the collection are fixed. Let me know if this helps at all.

<?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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文