【问题标题】:xslt group same nodes under parent as well as in child nodesxslt 在父节点和子节点下对相同的节点进行分组
【发布时间】:2015-05-15 13:56:41
【问题描述】:

我想在父标签(<Item>) 和子标签(<Sku>) 中对同名的节点进行分组。

<Item> 标记可能包含许多 <Sku> 子标记,但不应将它们分组,而应将每个 SkuItem 中的元素单独分组。

我有一个如下的输入 xml 文件:

<Products>
  <Item>
    <Dimensions>
      <Height>10</Height>
    </Dimensions>
    <Dimensions>
      <Weight>10</Weight>
    </Dimensions>
    <Color>
      <Attribute>Orange</Attribute>
    </Color>
    <Color>
      <Attribute>Blue</Attribute> 
    </Color>
    <Sku>
     <Dimensions>
      <Height>10</Height>
     </Dimensions>
     <Dimensions>
      <Weight>10</Weight>
     </Dimensions>
     <Color>
      <Attribute>Orange</Attribute>
     </Color>
     <Color>
      <Attribute>Blue</Attribute> 
     </Color>
    </Sku>
    <Sku>
     <Dimensions>
      <Height>10</Height>
     </Dimensions>
     <Dimensions>
      <Weight>10</Weight>
     </Dimensions>
     <Color>
      <Attribute>Orange</Attribute>
     </Color>
     <Color>
      <Attribute>Blue</Attribute> 
     </Color>
    </Sku>
   </Item>
</Products>   

预期输出如下:

<Products>
  <Item>
        <Dimensions>
            <Height>10</Height>
            <Weight>10</Weight>
        </Dimensions>
        <Color>
            <Attribute>Orange</Attribute>
            <Attribute>Blue</Attribute>
        </Color>
        <Sku>
        <Dimensions>
            <Height>10</Height>
            <Weight>10</Weight>
        </Dimensions>
        <Color>
            <Attribute>Orange</Attribute>
            <Attribute>Blue</Attribute>
        </Color>
     </Sku>
     <Sku>
        <Dimensions>
            <Height>10</Height>
            <Weight>10</Weight>
        </Dimensions>
        <Color>
            <Attribute>Orange</Attribute>
            <Attribute>Blue</Attribute>
        </Color>
    </Sku>
  </Item>
</Products>

任何帮助将不胜感激。 我在 xslt 下面使用了转换,但它只是“项目”下存在的组合元素。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="elements" match="Item/*[not(self::Sku)]" use="concat(name(), '|', generate-id(..))"/>

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Item">
    <xsl:copy>
        <xsl:apply-templates select="@*" />
        <xsl:for-each select="*[generate-id() = generate-id(key('elements', concat(name(), '|', generate-id(..)))[1])]">
            <xsl:copy>
                <xsl:apply-templates select="key('elements', concat(name(), '|', generate-id(..)))/*"/>
            </xsl:copy>
        </xsl:for-each>
        <xsl:apply-templates select="Item" />
    </xsl:copy>
</xsl:template>
</xsl:stylesheet> 

【问题讨论】:

    标签: xslt


    【解决方案1】:

    您可以在两个分组之间共享相同的逻辑,如下所示:

    <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="elements" match="*" use="concat(name(), '|', generate-id(..))"/>
    
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template name="GroupChildren">
        <xsl:param name="elements" select="*" />
    
        <xsl:for-each select="$elements[generate-id() = 
                                        generate-id(key('elements', 
                                                        concat(name(), '|', 
                                                               generate-id(..))
                                                       )[1])]">
          <xsl:copy>
            <xsl:apply-templates select="key('elements', 
                                             concat(name(), '|', generate-id(..)))/*"/>
          </xsl:copy>
        </xsl:for-each>
      </xsl:template>
    
      <xsl:template match="Item">
        <xsl:copy>
          <xsl:apply-templates select="@*" />
          <xsl:call-template name="GroupChildren">
            <xsl:with-param name="elements" select="*[not(self::Sku)]" />
          </xsl:call-template>
          <xsl:apply-templates select="Sku" />
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="Sku">
        <xsl:copy>
          <xsl:apply-templates select="@*" />
          <xsl:call-template name="GroupChildren" />
        </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    在您的示例输入上运行时,结果是:

    <Products>
      <Item>
        <Dimensions>
          <Height>10</Height>
          <Weight>10</Weight>
        </Dimensions>
        <Color>
          <Attribute>Orange</Attribute>
          <Attribute>Blue</Attribute>
        </Color>
        <Sku>
          <Dimensions>
            <Height>10</Height>
            <Weight>10</Weight>
          </Dimensions>
          <Color>
            <Attribute>Orange</Attribute>
            <Attribute>Blue</Attribute>
          </Color>
        </Sku>
        <Sku>
          <Dimensions>
            <Height>10</Height>
            <Weight>10</Weight>
          </Dimensions>
          <Color>
            <Attribute>Orange</Attribute>
            <Attribute>Blue</Attribute>
          </Color>
        </Sku>
      </Item>
    </Products>
    

    【讨论】:

      猜你喜欢
      • 2017-12-06
      • 2018-04-20
      • 2012-08-07
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      • 2021-12-05
      • 2017-09-02
      • 1970-01-01
      相关资源
      最近更新 更多