使用XSLT从XML中删除标记内的冗余标记

时间:2017-08-21 04:16:09

标签: xml xslt bi-publisher

我在input.xml文件中获得了以下数据,它包含<I>标记之外的<TD>个标记,这些标记在BI报告生成中产生了问题。请帮助使用XSLT代码来整理此XML。欢迎提出任何建议。

<TABLE border="1" cellSpacing="0" cellPadding="0">
    <TBODY>
        <TR></TR>
        <TR>
            <TD vAlign="top" width="402">
                <P>
                    <B>Column Heading here </B>
                </P>
            </TD>
            <TD vAlign="top" width="234">
                <P>
                    <B>Another Heading</B>
                </P>
            </TD>
        </TR>
        <TR>
            <TD vAlign="top" width="402">
                <P>
                    <I>
                        Item for discount
                        <I></I>
                    </I>
                </P>
                <I>
                    <I></I>
                </I>
            </TD>
            <I>
                <I>
                    <TD vAlign="top" width="234">
                        <P align="center">
                            <I>%</I>
                        </P>
                        <I>
                            <I></I>
                        </I>
                    </TD>
                    <I>
                        <I></I>
                    </I>
                </I>
            </I>
        </TR>
        <I>
            <I>
                <I>
                    <I>
                        <TR>
                            <TD vAlign="top" width="402">
                                <P>
                                    <I>
                                        Item for discount
                                        <I></I>
                                    </I>
                                </P>
                                <I>
                                    <I></I>
                                </I>
                            </TD>
                            <I>
                                <I>
                                    <TD vAlign="top" width="234">
                                        <I>
                                            <P align="center">
                                                <I>%</I>
                                            </P>
                                        </I>
                                        <I>
                                            <I></I>
                                        </I>
                                    </TD>
                                    <I>
                                        <I></I>
                                    </I>
                                </I>
                            </I>
                        </TR>
                        <I>
                            <I>
                                <I>
                                    <I></I>
                                </I>
                            </I>
                        </I>
                    </I>
                </I>
            </I>
        </I>
    </TBODY>
</TABLE>

预期输出:(**之间的**标记应删除)

<TABLE border="1" cellSpacing="0" cellPadding="0">
    <TBODY>
        <TR></TR>
        <TR>
            <TD vAlign="top" width="402">
                <P>
                    <B>Column Heading here </B>
                </P>
            </TD>
            <TD vAlign="top" width="234">
                <P>
                    <B>Another Heading</B>
                </P>
            </TD>
        </TR>
        <TR>
            <TD vAlign="top" width="402">
                <P>
                    <I>
                        Item for discount
                        <I></I>
                    </I>
                </P>
                <I>
                    <I></I>
                </I>
            </TD>
            **
            <I>
                <I>
                    **
                    <TD vAlign="top" width="234">
                        <P align="center">
                            <I>%</I>
                        </P>
                        <I>
                            <I></I>
                        </I>
                    </TD>
                    **
                    <I>
                        <I></I>
                    </I>
                </I>
            </I>
            **
        </TR>
        **
        <I>
            <I>
                <I>
                    <I>
                        **
                        <TR>
                            <TD vAlign="top" width="402">
                                <P>
                                    <I>
                                        Item for discount
                                        <I></I>
                                    </I>
                                </P>
                                <I>
                                    <I></I>
                                </I>
                            </TD>
                            **
                            <I>
                                <I>
                                    **
                                    <TD vAlign="top" width="234">
                                        <I>
                                            <P align="center">
                                                <I>%</I>
                                            </P>
                                        </I>
                                        <I>
                                            <I></I>
                                        </I>
                                    </TD>
                                    **
                                    <I>
                                        <I></I>
                                    </I>
                                </I>
                            </I>
                            **
                        </TR>
                        **
                        <I>
                            <I>
                                <I>
                                    <I></I>
                                </I>
                            </I>
                        </I>
                    </I>
                </I>
            </I>
        </I>
        **
    </TBODY>
</TABLE>

2 个答案:

答案 0 :(得分:0)

只需创建一个匹配<I>兄弟姐妹的<TD>元素的模板:

<xsl:template match="I[preceding-sibling::TD | following-sibling::TD ]">
        <xsl:apply-templates/>
    </xsl:template>

由于<xsl:apply-templates>默认行为只是复制文本节点,如果在您提供的示例中,<I>元素为空,则它不会将它们复制到输出中。

如果您希望它是递归的,您可以将子项添加到匹配项中:

<xsl:template match="I[preceding-sibling::TD | following-sibling::TD | ancestor::I[preceding-sibling::TD | following-sibling::TD] ]">
        <xsl:apply-templates/>
    </xsl:template>

更新: 如果您只想删除拥有<I>兄弟姐妹及其<TD>个孩子的<I>个元素,那么您可以使用:

<xsl:template match="I[preceding-sibling::TD | following-sibling::TD | parent::I[preceding-sibling::TD | following-sibling::TD] ]">
        <xsl:apply-templates/>
    </xsl:template>

这实际上是非常基本的Xpath。如果您经常处理此类问题,我强烈建议您花一两个小时阅读有关Xpath的内容。这非常值得。

答案 1 :(得分:0)

感谢您的回答。 创建了更通用的解决方案: 它将删除

之间的所有空标记

</TD> $<TD> and </TR> $ </TBODY>

, $ - 表示任何空标记。

<xsl:template match="//*[ancestor::TR and not(ancestor::TD) and not(self::TD)]">
    <xsl:apply-templates/>

<xsl:template match="//*[ancestor::TBODY and not(ancestor::TR) and not(self::TR)]">
    <xsl:apply-templates/>