打破外部模板规则并为死者创建新规则

时间:2017-03-27 11:33:30

标签: xslt xslt-2.0

我有一种情况,我必须制动XSLT流程以将某些标签(带属性)包装到另一个标签中。让我解释: 目前在我的XSLT(下面)中,外部主题标签启动了一个包装器pagesequence元素。我想在遇到pagesequence时破坏外部<p ouputclass=special>代码,并且适合新的pagesequence

输入:

<root>
<topic>
    <p>Outertopic1Para1</p>
    <p>Outertopic1Para2</p>
</topic>
<topic>
    <p>Outertopic2Para1</p>
    <p>Outertopic2Para2</p>
</topic>
<topic>
    <p>Outertopic3Para1</p>
    <p>Outertopic3Para2</p>
    <topic>
        <p outputclass="special">specialPara3</p>
        <p>Innertopic1Para4</p>           
    </topic>
</topic>
<topic>
    <p>Outertopic4Para1</p>
    <p>Outertopic4Para2</p>
    <topic>
        <p outputclass="special">specialPara3</p>
        <p>Innertopic1Para4</p>
    </topic>
</topic>
</root>

预期输出:

        <?xml version="1.0" encoding="UTF-8"?>
    <root>
        <page-sequence page="pageNum()" marster-refrence="portrait">
            <foblock>
                <foblock>
                    <p>Outertopic1Para1</p>
                </foblock>
                <foblock>
                    <p>Outertopic1Para2</p>
                </foblock>
            </foblock>
        </page-sequence>
        <page-sequence page="pageNum()" marster-refrence="portrait">
            <foblock>
                <foblock>
                    <p>Outertopic2Para1</p>
                </foblock>
                <foblock>
                    <p>Outertopic2Para2</p>
                </foblock>
            </foblock>
        </page-sequence>
        <page-sequence page="pageNum()" marster-refrence="portrait">
            <foblock>
                <foblock>
                    <p>Outertopic3Para1</p>
                </foblock>
                <foblock>
                    <p>Outertopic3Para2</p>
                </foblock>
                <foblock> </foblock>
            </foblock>
        </page-sequence>
        <page-sequence marster-refrence="special">
            <foblock>
                <p outputclass="special">specialPara3</p>
            </foblock>
        </page-sequence>
        <page-sequence>
            <foblock>
                <p>Innertopic1Para4</p>
            </foblock>
        </page-sequence>
        <page-sequence page="pageNum()" marster-refrence="portrait">
            <foblock>
                <foblock>
                    <p>Outertopic4Para1</p>
                </foblock>
                <foblock>
                    <p>Outertopic4Para2</p>
                </foblock>
            </foblock>
        </page-sequence>
        <page-sequence marster-refrence="special">
            <foblock>
                <p outputclass="special">specialPara3</p>
            </foblock>
        </page-sequence>
        <page-sequence page="pageNum()" marster-refrence="portrait">
            <foblock>
                <p>Innertopic1Para4</p>
            </foblock>
        </page-sequence>
    </root>

示例XSLT,我试图在这里创建测试xslt,但是可以在下面的代码之上实现这一点,这样我就不必调整其余的DITA-OT流程:

<?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="2.0">

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

<xsl:template match="topic">
    <xsl:choose>
        <xsl:when test="ancestor::topic">
            <foblock>
                <xsl:apply-templates/>
            </foblock>
        </xsl:when>
        <xsl:otherwise>
            <page-sequence page="pageNum()" marster-refrence="potrait">
                <foblock>
                    <xsl:apply-templates/>
                </foblock>
            </page-sequence>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="p">
    <foblock>
        <xsl:copy-of select="."/>
    </foblock>
</xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

我认为您的xsl:otherwise可以更改为仅选择非topic个节点,然后在创建块后单独选择topic个语句

<xsl:otherwise>
   <page-sequence page="pageNum()" marster-refrence="potrait">
      <foblock>
         <xsl:apply-templates select="node() except topic"/>
      </foblock>
   </page-sequence>
   <xsl:apply-templates select="topic"/>
</xsl:otherwise>

然后,您需要一个单独的模板来处理后代p元素中的topic元素

<xsl:template match="topic[ancestor::topic]/p">

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">

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

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

<xsl:template match="topic">
    <xsl:choose>
        <xsl:when test="ancestor::topic">
            <xsl:apply-templates/>
        </xsl:when>
        <xsl:otherwise>
            <page-sequence page="pageNum()" marster-refrence="potrait">
                <foblock>
                    <xsl:apply-templates select="node() except topic"/>
                </foblock>
            </page-sequence>
            <xsl:apply-templates select="topic"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="p">
    <foblock>
        <xsl:copy-of select="."/>
    </foblock>
</xsl:template>

<xsl:template match="topic[ancestor::topic]/p">
    <page-sequence>
        <xsl:if test="@outputclass='special'">
            <xsl:attribute name="marster-refrence" select="'special'" />
        </xsl:if>
        <foblock>
            <xsl:copy-of select="."/>
        </foblock>
    </page-sequence>
</xsl:template>
</xsl:stylesheet>