具有父节点的xslt递归子节点

时间:2016-12-19 10:11:02

标签: xml xslt xslt-2.0

我想知道在xslt 2.0中解决此解决方案的更好方法。

输入:

<Root>
    <Record>
        <FName>Abc</FName>
        <MName>FAbc</MName>
        <Kid>
            <CName>C1Abc<CName>
        </Kid>
        <Kid>
            <CName>C2Abc<CName>
        </Kid>
    </Record>
    <Record>
        <FName>Def</FName>
        <MName>FDef</MName>
        <Kid>
            <CName>C1Def<CName>
        </Kid>
    </Record>
    <Record>
        <FName>Xyz</FName>
        <MName>FXyz</MName>
    </Record>
</Root>

输出:

<Root>
    <Record>
        <FName>Abc</FName>
        <MName>FAbc</MName>
        <CName>C1Abc<CName>
    </Record>
    <Record>
        <FName>Abc</FName>
        <MName>FAbc</MName>
        <CName>C2Abc<CName>
    </Record>
    <Record>
        <FName>Def</FName>
        <MName>FDef</MName>
        <CName>C1Def<CName>
    </Record>
    <Record>
        <FName>Xyz</FName>
        <MName>FXyz</MName>
        <CName></CName>
    </Record>
</Root>

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    version="2.0">

    <xsl:template match="Root">
        <Root>
            <xsl:apply-templates select="Record">
            </xsl:apply-templates>
        </Root>
    </xsl:template>

    <xsl:template match="Record">
        <xsl:choose>
            <xsl:when test="Kid">
                <xsl:apply-templates select="Kid">                              
                </xsl:apply-templates>  
            </xsl:when>
            <xsl:otherwise>
                <Record>   
                    <FName>
                        <xsl:value-of select="FName"/>
                    </FName>
                    <MName>
                        <xsl:value-of select="MName"/>
                    </MName>        
                    <CName>
                        <xsl:value-of select="Kid/CName"/>
                    </CName>
                </Record>                                   
            </xsl:otherwise>
        </xsl:choose>       
    </xsl:template>

    <xsl:template match="Kid">  
        <Record>   
            <FName>
                <xsl:value-of select="../FName"/>
            </FName>
            <MName>
                <xsl:value-of select="../MName"/>
            </MName>
            <CName> 
                <xsl:value-of select="CName"/>
            </CName>            
        </Record>               
    </xsl:template>
</xsl:stylesheet>

我的xslt有效,我能够得到我期望的输出。但我想知道是否还有其他更好的方法来做到这一点。主要是为了避免任何性能问题,因为将有数千条记录包含更多数据。谢谢。

1 个答案:

答案 0 :(得分:0)

你可以改写

<xsl:template match="Record">
    <xsl:choose>
        <xsl:when test="Kid">
            <xsl:apply-templates select="Kid">                              
            </xsl:apply-templates>  
        </xsl:when>
        <xsl:otherwise>
            <Record>   
                <FName>
                    <xsl:value-of select="FName"/>
                </FName>
                <MName>
                    <xsl:value-of select="MName"/>
                </MName>        
                <CName>
                    <xsl:value-of select="Kid/CName"/>
                </CName>
            </Record>                                   
        </xsl:otherwise>
    </xsl:choose>       
</xsl:template>

作为

<xsl:template match="Record[not(Kid)]">
            <Record>   
                <FName>
                    <xsl:value-of select="FName"/>
                </FName>
                <MName>
                    <xsl:value-of select="MName"/>
                </MName>        
                <CName></CName>
            </Record>                                       
</xsl:template>

<xsl:template match="Record[Kid]">
  <xsl:apply-templates select="Kid"/>
</xsl:template>