Split specific element attribute into multiple rows based on delimiter

后端 未结 1 569
闹比i
闹比i 2021-01-28 16:16

I am trying to transform an XML and split the third App_Data element Value into multiple duplicate rows based on the commas from:

    
        &l         


        
相关标签:
1条回答
  • 2021-01-28 16:34

    it only makes the attributes into child -elements when I need attributes

    Actually, your example shows that you do need an element for each token.

    Try it this way:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="App_Data[@Name='Category']">
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="@Value"/>
        </xsl:call-template>
    </xsl:template>
    
    <xsl:template name="tokenize">
        <xsl:param name="text"/>
        <xsl:param name="delimiter" select="', '"/>
            <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
            <xsl:if test="$token">
                <App_Data App="{@App}" Name="Category" Value="{$token}"/>
            </xsl:if>
            <xsl:if test="contains($text, $delimiter)">
                <!-- recursive call -->
                <xsl:call-template name="tokenize">
                    <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                </xsl:call-template>
            </xsl:if>
    </xsl:template>
    
    </xsl:stylesheet>
    

    Or, if you prefer a shorter (but non-reusable) version:

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <!-- identity transform -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="App_Data[@Name='Category']" name="tokenize">
        <xsl:param name="text" select="@Value"/>
        <xsl:param name="delimiter" select="', '"/>
            <xsl:variable name="token" select="substring-before(concat($text, $delimiter), $delimiter)" />
            <xsl:if test="$token">
                <App_Data App="{@App}" Name="Category" Value="{$token}"/>
            </xsl:if>
            <xsl:if test="contains($text, $delimiter)">
                <!-- recursive call -->
                <xsl:call-template name="tokenize">
                    <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                </xsl:call-template>
            </xsl:if>
    </xsl:template>
    
    </xsl:stylesheet>
    
    0 讨论(0)
提交回复
热议问题