XSLT分组递归问题

伙计们,分组的递归不起作用。我正在使用XSLT 1.0。 我需要一些帮助来解决这个问题。提前致谢。 背景: 我在xml中有3种不同的类型(常见,类别和复杂)。我的目标是。 1 - 基于类型分组xml节点。 2 - 在Type = common下为复合体创建子组。 3 - 对于Type = complex,根据源xml创建多个集合。在每个集合中,它应仅列出4个元素,其中Name ='A'或'B'或'C'或'D'。 这就是我遇到问题的地方。分组和子分组工作正常。但是,当我尝试使用递归创建一个集合时,它并没有给我打算输出。有关参考,请参阅预期的xml样本。 源XML:
<?xml version="1.0" encoding="Windows-1252"?>
<XML>
  <Attributes>
    <Attribute>
      <Name>Buyer ID</Name>
      <Type>common</Type>
      <Value>Lee</Value>
    </Attribute>
    <Attribute>
      <Name>Enviornment</Name>
      <Type>common</Type>
      <Value>Dev</Value>
    </Attribute>
    <Attribute>
      <Name>Retail</Name>
      <Type>common</Type>
      <Value></Value>
    </Attribute>
    <Attribute>
      <Name>Gender</Name>
      <Type>category</Type>
      <Value>M</Value>
    </Attribute>
    <Attribute>
      <Name>Collection</Name>
      <Type>Complex</Type>
      <Value>ing</Value>
      <Path />
    </Attribute>
    <Attribute>
      <Name>A</Name>
      <Type>Complex</Type>
      <Value>Testing</Value>
      <Path />
    </Attribute>
    <Attribute>
      <Name>B</Name>
      <Type>Complex</Type>
      <Value>Yellow</Value>
      <Path />
    </Attribute>
    <Attribute>
      <Name>C</Name>
      <Type>Complex</Type>
      <Value>10</Value>
      <Path />
    </Attribute>
    <Attribute>
      <Name>D</Name>
      <Type>Complex</Type>
      <Value>MA</Value>
      <Path />
    </Attribute>
    <Attribute>
      <Name>A</Name>
      <Type>Complex</Type>
      <Value>24a</Value>
      <Path />
    </Attribute>
    <Attribute>
      <Name>B</Name>
      <Type>Complex</Type>
      <Value>Green</Value>
      <Path />
    </Attribute>
    <Attribute>
      <Name>C</Name>
      <Type>Complex</Type>
      <Value>22</Value>
      <Path />
    </Attribute>
    <Attribute>
      <Name>D</Name>
      <Type>Complex</Type>
      <Value>AM</Value>
      <Path />
    </Attribute>
  </Attributes>
</XML>
预期产出:
<?xml version="1.0" encoding="utf-8"?>
<Data Schema="XML A">
  <Items>
    <Item>
      <Attributes type="common">
        <Attr name="Buyer ID" value="Lee" />
        <Attr name="Enviornment" value="Dev" />
        <Attr name="Retail" value="" />
        <Collection name="Collection" >
          <Complex>
            <Attr name="A" value="Testing" />
            <Attr name="B" value="Yellow" />
            <Attr name="C" value="10" />
            <Attr name="D" value="MA" />
          </Complex>
          <Complex>
            <Attr name="A" value="24a" />
            <Attr name="B" value="Green" />
            <Attr name="C" value="22" />
            <Attr name="D" value="AM" />
          </Complex>
        </Collection>
      </Attributes>
      <Attributes type="category">
        <Attr name="Gender" value="M" />
      </Attributes>
      <errorCodes>
        <errorCode>value for Retail is missing.</errorCode>
      </errorCodes>
    </Item>
  </Items>
</Data>
这是XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="type" match="Attribute" use="Type"/>
    <xsl:variable name="group" select="4"/>
    <xsl:template match="/">
        <Data Schema="XML A">
            <Items>
                <Item>
                    <xsl:apply-templates select="XML/Attributes/Attribute[generate-id() = generate-id(key('type', Type)[1])]">
                        <xsl:sort select="Type" order="descending"/>
                    </xsl:apply-templates>
                    <errorCodes>
                        <xsl:apply-templates select="XML/Attributes/Attribute" mode="errors"/>
                    </errorCodes>
                </Item>
            </Items>
        </Data>
    </xsl:template>
    <xsl:template match="Attribute">
        <xsl:variable name="compType" select="count(/XML/Attributes/Attribute[Type='Complex' and Name!='Collection'])"/>
        <xsl:if test="Type!='Complex'">
            <Attributes type="{Type}">
                <xsl:apply-templates select="key('type',Type)" mode="out"/>
                <xsl:if test="Type='common'">
                    <Collection>
                        <xsl:for-each select="/XML/Attributes/Attribute[Type='Complex']">
                            <xsl:choose>
                                <xsl:when test="(Name='A' or Name='B' or Name='C' or Name='D')">
                                    <xsl:if test="(($compType > 0) and (Name!='Collection'))">
                                        <xsl:apply-templates select="key('type','Complex')" mode="out"/>
                                    </xsl:if>
                                </xsl:when>
                                <xsl:otherwise>
                                    <Complex>
                                        <Attr id="" name="A" value="Default" />
                                        <Attr id="" name="B" value="Default" />
                                        <Attr id="" name="C" value="Default" />
                                        <Attr id="" name="D" value="" />
                                    </Complex>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:for-each>
                    </Collection>
                </xsl:if>
            </Attributes>
        </xsl:if>
    </xsl:template>
    <xsl:template match="Attribute" mode="out">
        <Collection>
            <Attr name="{Name}" value="{Value}"/>
        </Collection>
    </xsl:template>
    <xsl:template match="Attribute[Type='Complex']" mode="out">
        <xsl:apply-templates select="XML/Attributes/Attribute[not(Name='Collection')]
                                                [position() mod $group = 1]" mode="group"/>
    </xsl:template>
    <xsl:template match="Name" mode="group">
        <xsl:if test="Name!='Collection'">
            <Attr name="{Name}" value="{Value}"/>
        </xsl:if>
    </xsl:template>
    <xsl:template match="Attribute">
        <Complex>
            <xsl:apply-templates
                select=".|following-sibling::Attribute[position() &lt; $group]" mode="inner" />
        </Complex>
    </xsl:template>
    <xsl:template match="Attribute" mode="errors">
        <xsl:if test="(Name='Retail' or Name='Product Description') and Value=''">
            <errorCode>value for <xsl:value-of select="Name"/> is missing.</errorCode>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
    
已邀请:
我不确定我是否了解您的所有要求,但以下示例
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:data="http://example.com/data"
  exclude-result-prefixes="data"
  version="1.0">

  <xsl:output indent="yes"/>

  <xsl:key name="att-by-type" match="Attributes/Attribute" use="Type"/>

  <xsl:variable name="complex" select="key('att-by-type', 'Complex')"/>

  <xsl:template match="XML">
    <Data Schema="XML A">
      <Items>
        <Item>
          <xsl:apply-templates select="Attributes/Attribute[Type = 'common' or Type = 'category'][generate-id() = generate-id(key('att-by-type', Type)[1])]" mode="group"/>
        </Item>
      </Items>
    </Data>
  </xsl:template>

  <xsl:template match="Attribute" mode="group">
    <Attributes type="{Type}">
      <xsl:apply-templates select="key('att-by-type', Type)"/>
      <xsl:if test="Type = 'common'">
        <Collection name="Collection">
          <xsl:apply-templates select="$complex[Name = 'A']" mode="comp-group"/>
        </Collection>
      </xsl:if>
    </Attributes>
  </xsl:template>

  <xsl:template match="Attribute" mode="comp-group">
    <Complex>
      <xsl:variable name="pos" select="position()"/>
      <xsl:apply-templates select="$complex[Name = 'A'][position() = $pos] |
                                   $complex[Name = 'B'][position() = $pos] |
                                   $complex[Name = 'C'][position() = $pos] |
                                   $complex[Name = 'D'][position() = $pos]"/>
    </Complex>
  </xsl:template>

  <xsl:template match="Attribute">
    <Attr name="{Name}" value="{Value}"/>
  </xsl:template>

</xsl:stylesheet>
产生你发布的输出(除了errorCodes,我把它留下来,因为它似乎与另一个问题无关)。     

要回复问题请先登录注册