如何使用具有不同数据结构的XSLT替换公共节点XML?

时间:2016-08-24 12:05:34

标签: xml xslt data-structures xml-parsing xslt-1.0

我试图在基于html的文本中转换Flash文本格式。

XML Source。

<TEXTFORMAT LEADING="2">
    <P ALIGN="RIGHT">
        <FONT FACE="Lato" SIZE="12" COLOR="#4B4B4B" LETTERSPACING="0" KERNING="0">left tefxt </FONT>
    </P>
</TEXTFORMAT>
<TEXTFORMAT LEADING="2">
    <P ALIGN="JUSTIFY">
        <FONT FACE="Lato" SIZE="12" COLOR="#4B4B4B" LETTERSPACING="0" KERNING="0">@#dgsdg
            <FONT FACE="Gabriola">sdfgdfg</FONT> dsfg df
            <FONT SIZE="16">gdsfg</FONT>sd sd
            <I>fg df</I> gsdg sdgfgsd gdfg </FONT>
    </P>
</TEXTFORMAT>
<TEXTFORMAT LEADING="2">
    <P ALIGN="JUSTIFY">
        <FONT FACE="Lato" SIZE="12" COLOR="#4B4B4B" LETTERSPACING="0" KERNING="0">fdsgd sdfg </FONT>
    </P>
</TEXTFORMAT>
<TEXTFORMAT LEADING="2">
    <P ALIGN="LEFT">
        <FONT FACE="Lato" SIZE="12" COLOR="#4B4B4B" LETTERSPACING="0" KERNING="0"> reter erret erret wertwer tert</FONT>
    </P>
</TEXTFORMAT>
<TEXTFORMAT LEADING="2">
    <P ALIGN="LEFT">
        <FONT FACE="Lato" SIZE="12" COLOR="#4B4B4B" LETTERSPACING="0" KERNING="0">ertyryrt</FONT>
    </P>
</TEXTFORMAT>

我需要访问转换所有字体元素

<FONT FACE="Lato" SIZE="12" COLOR="#4B4B4B" LETTERSPACING="0" KERNING="0">@#dgsdg
                    <FONT FACE="Gabriola">sdfgdfg</FONT> dsfg df
                    <FONT SIZE="16">gdsfg</FONT>sd sd
                    <I>fg df</I> gsdg sdgfgsd gdfg </FONT>

进入像这样的结构

<span style="font-family:Lato; font-size:12px; color:#4B4B4B;">
  @#dgsdg<span style="font-family:Gabriola;">sdfgdfg</span> dsfg df
  <span style="font-size:16px;">gdsfg</span>sd sd
                <i>fg df</i> gsdg sdgfgsd gdfg
</span>

上述数据结构有很多不同(字体块)。

如何更换所有标签并添加样式。 是否可以遍历子节点的子节点?

我的XSLT

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html" indent="yes"/>

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

    <xsl:template match="div">
    <xsl:strip-space elements="*"/>
        <div>
            <xsl:for-each select="TEXTFORMAT">
                <xsl:if test="P">
                    <span>
                        <xsl:attribute name="style">
                            <xsl:value-of select="'align:'" /><xsl:value-of select="P/@ALIGN" />;
                        </xsl:attribute>
                        <xsl:for-each select="P/FONT">
                            <span>
                                <xsl:attribute name="style">
                                    <xsl:value-of select="'font-family:'" /><xsl:value-of select="@FACE" />;
                                    <xsl:value-of select="'font-size:'" /><xsl:value-of select="@SIZE" />;
                                    <xsl:value-of select="'color:'" /><xsl:value-of select="@COLOR" />;
                                </xsl:attribute>
                            </span>
                        </xsl:for-each>
                    </span>
                    <br/>
                </xsl:if>

        </div>
     </xsl:template>

</xsl:stylesheet>

注意:标签内可能有n个标签

1 个答案:

答案 0 :(得分:1)

也许你需要类似的东西(注意我已经在输入xml中添加了<root>标签以使其有效)

<?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"
    exclude-result-prefixes="xs"
    version="1.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes" method="html"/>

    <!-- identity template -->

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

    <xsl:template match="root">
        <div>
            <xsl:apply-templates/>
        </div>
    </xsl:template>

    <xsl:template match="FONT">
        <span>
            <xsl:attribute name="style">
                <!-- collect attributes -->
                <xsl:variable name="styles">
                    <xsl:if test="@FACE">
                        <xsl:value-of select="concat('font-family:', @FACE)"/>
                        <xsl:text>; </xsl:text>
                    </xsl:if>
                    <xsl:if test="@SIZE">
                        <xsl:value-of select="concat('font-size:', @SIZE, 'px')"/>
                        <xsl:text>; </xsl:text>
                    </xsl:if>
                    <xsl:if test="@COLOR">
                        <xsl:value-of select="concat('color:', @COLOR)"/>
                        <xsl:text>;</xsl:text>
                    </xsl:if>
                </xsl:variable>
                <!-- delete trailing spaces -->
                <xsl:value-of select="normalize-space($styles)"/>
            </xsl:attribute>
            <xsl:apply-templates/>
        </span>
    </xsl:template>

    <!-- remove unwanted attributes -->
    <xsl:template match="@LETTERSPACING|@KERNING"/>

    <xsl:template match="I">
        <i><xsl:apply-templates/></i>
    </xsl:template>

</xsl:stylesheet>