打破祖先的内容 - XSLT

时间:2018-03-07 00:59:26

标签: xslt xslt-2.0

我正在使用xslt对xml进行xml转换,并且我已经卡在一个地方。情景就是这样,

    <doc>
    <tbl>
        <entry>
            <para>aaaa2</para>
            <para>aaaa2</para>
        </entry>
        <entry>
            <para>zzz</para>
            <para>zzz2</para>
        </entry>
        <entry>
            <para>bbbb1</para>
            <para>bbbb2</para>
            <tbl>
                <entry>
                    <para>cccc1</para>
                    <para>cccc2</para>
                </entry>
                <entry>
                    <para>ddd1</para>
                    <para>ddd3</para>
                </entry>
                <entry>
                    <new-tbl/>
                    <para>eee</para>
                </entry>
                <entry>
                    <para>fff</para>
                </entry>
                <entry>
                    <para>ggg</para>
                </entry>
            </tbl>
        </entry>
        <entry>
            <para>hhh</para>       
        </entry>
        <entry>
            <para>iii1</para>
            <para>1112</para>
        </entry>
    </tbl>
</doc>

以下是源xml,其他<tbl>内可以有<tbl>

我需要用这个

做两件事
  • 如果<tbl>在另一个<tbl>中找到,则会从anscetor <tbl>
  • 中删除它
  • 如果在<new-tbl/>内找到<entry>,请创建一个新<tbl>并将其从anscetor <tbl>
  • 中删除

所需的输出xml,

<doc>
    <tbl>
        <entry>
            <para>aaaa2</para>
            <para>aaaa2</para>
        </entry>
        <entry>
            <para>zzz</para>
            <para>zzz2</para>
        </entry>
    </tbl>
    <tbl>
        <entry>
            <para>bbbb1</para>
            <para>bbbb2</para>
        </entry>
    </tbl>
    <tbl>
        <entry>
            <para>cccc1</para>
            <para>cccc2</para>
        </entry>
        <entry>
            <para>ddd1</para>
            <para>ddd3</para>
        </entry>
    </tbl>
    <tbl> 
        <entry>
            <new-tbl/>
            <para>eee</para>
        </entry>
    </tbl>
    <tbl>
        <entry>
            <para>fff</para>
        </entry>
        <entry>
            <para>ggg</para>
        </entry>
    </tbl>
    <tbl>
        <entry>
            <para>hhh</para>
        </entry>
        <entry>
            <para>iii1</para>
            <para>1112</para>
        </entry>
    </tbl>
</doc>

第一个要求是通过使用for-each循环完成的。

<xsl:template match="tbl[descendant::tbl]">
        <xsl:for-each select="entry">
            <tbl>
                <entry>
                    <xsl:apply-templates select="node()[not(self::tbl)]"/>
                </entry>
            </tbl>
            <xsl:apply-templates select="tbl"/>
        </xsl:for-each>
    </xsl:template>

我的问题是扩展此代码以实现第二个要求。

1 个答案:

答案 0 :(得分:1)

首先,我们必须有一个身份模板:

<asp:CommandField ButtonType="Image" ShowDeleteButton="True" HeaderStyle-BackColor="LightBlue" DeleteImageUrl="~/images/remove.png" ItemStyle-Width="2%"></asp:CommandField>

现在,我们必须创建将表推送到外面的命名模板。如:

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

然后,以下是第一个<!-- this will move entry nodes with tbl descendants --> <xsl:template name="move_tbl"> <xsl:param name="cells"/> <xsl:for-each-group select="$cells" group-adjacent="boolean(self::entry[not(descendant::tbl) and not(descendant::new-tbl)])"> <xsl:choose> <xsl:when test="current-grouping-key()"> <tbl> <xsl:apply-templates select="current-group()"/> </tbl> </xsl:when> <xsl:otherwise> <xsl:choose> <xsl:when test="current-group()[new-tbl]"> <tbl> <xsl:apply-templates select="current-group()"/> </tbl> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="current-group()"/> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </xsl:template> <!-- this will move tbl nodes outside of entry nodes --> <xsl:template name="move_tbl_sibling_para"> <xsl:param name="cells"/> <xsl:for-each-group select="$cells" group-adjacent="boolean(self::para)"> <xsl:choose> <xsl:when test="current-grouping-key()"> <tbl> <entry> <xsl:apply-templates select="current-group()"/> </entry> </tbl> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="current-group()"/> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </xsl:template> 节点,tbl节点与tbl祖先节点和tbl节点

的模板匹配
entry

整个样式表如下:

<xsl:template match="entry">
    <xsl:choose>
        <xsl:when test="tbl">
            <xsl:call-template name="move_tbl_sibling_para">
                <xsl:with-param name="cells" select="node()[not(self::tbl)]"/>
            </xsl:call-template>
            <xsl:apply-templates select="tbl"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy-of select="."/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="tbl[ancestor::tbl]">
    <xsl:call-template name="move_tbl">
        <xsl:with-param name="cells" select="node()"/>
    </xsl:call-template>
</xsl:template>

<xsl:template match="doc/tbl">
    <xsl:call-template name="move_tbl">
        <xsl:with-param name="cells" select="node()"/>
    </xsl:call-template>
</xsl:template>