基于属性值 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>
我关注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>