基于属性值 ID 的 XSLT 重组

XSLT Regrouping based on attribute value ID

我关注XML

<group id="a">
<Name>Number One</Name>
<setgroup>
<refgroup ID="b">
<refgroup ID="c">
</setgroup>
</group>


<group id="b">
<Name>Number Two</Name>
<setgroup>
<refgroup ID="c">
<refgroup ID="e">
</setgroup>
</group>

<group id="c">
<Name>Number Three</Name>
<setgroup>
<refgroup ID="g">
<refgroup ID="f">
</setgroup>
</group>

作为输出我需要

<Product>
   <Name>Number One</Name>
   <Product>
    <Name>Number Two</Name>
       <Product>
          <Name>Number Three</Name>
       </Product>
   </Product>
</Product>

所以基本上,一旦我遍历该节点,我的新 xml 就不会再次包含在其中。

所以我需要根据我的xslt重新树

我目前拥有的:

<Products>
                <xsl:for-each select="*:PIMXMLExport[fn:namespace-uri() eq '']/*:group[fn:namespace-uri() eq '']">
                    <Product>
                        <Name>
                            <xsl:for-each select="(./*:Name[fn:namespace-uri() eq '']/node())[fn:boolean(self::text())]">
                                <xsl:sequence select="fn:string(.)"/>
                            </xsl:for-each>
                        </Name>
                        <xsl:for-each select="*:setgroup[fn:namespace-uri() eq '']/*:refgroup[fn:namespace-uri() eq '']">
                            <Product>
                                    <Name>
                                     <xsl:variable name="header_pos" select="@OIDRef"/>
                                        <xsl:value-of select="/PIMXMLExport/group[@asimoid = $header_pos]/Name"/>
                                    </Name>
                            </Product>
                        </xsl:for-each> 
                    </Product>
                </xsl:for-each>
            </Products>

如果您按照设计使用 XSLT 的方式使用 XSLT,这是其中一个问题,它会变得非常容易:使用 xsl:apply-模板和模板规则而不是嵌套 xsl:for-每个和条件。

解决方案的关键方面是:

(a) 处理 <group> 个元素的模板规则:

<xsl:template match="group">
<Product>
  <xsl:copy-of select="Name"/>
  <xsl:apply-templates/>
</Product>
</xsl:template>

(b) 按 ID 查找组的键

<xsl:key name="gpKey" match="group" use="id"/>

(c) 匹配 refgroup 元素的模板规则:

<xsl:template match="refgroup">
  <xsl:apply-templates select="key('gpKey', @ID)"/>
</xsl:template>