簡體   English   中英

XSLT-將模板應用於子節點和text()節點

[英]XSLT - apply-templates to child node and text() node

我有一個這樣的xml文件,

<content>
    <ol>
        <li> List<span style="color: rgb(255,0,255);">The scopeeeee of</span>this project is
            <ol>
                <li>nested list1</li>
                <li>nested <span style="color: rgb(255,0,255);">The scope of this project is</span> list1</li>
                <li>nested list1</li>
                <li>nested list1</li>
                <li>nested list1</li>
            </ol>
        </li>
        <li>
            <p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p>
        </li>
        <li>
            <p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p>
        </li>
    </ol>
</content>

我需要使用XSLT將以上xml轉換為以下xml

預期的輸出,

<content>
    <orderedList>
        <liItem>
            <para>List<c type="color: rgb(255,0,255);">The scopeeeee of this project is to:</c>jkhsdlkjfh</para>
        </liItem>
        <orderedList>
            <liItem>
                <para>nested list1</para>
            </liItem>
            <liItem>
                <para>nested <c type="color: rgb(255,0,255);">The scope of this project is</c>list1</para>
            </liItem>
            <liItem>
                <para>nested list1</para>
            </liItem>
            <liItem>
                <para>nested list1</para>
            </liItem>
            <liItem>
                <para>nested list1</para>
            </liItem>
        </orderedList>

        <liItem>
            <para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para>
        </liItem>
        <liItem>
            <para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para>
        </liItem>
    </orderedList>
</content>

如您所見,li項目中的文本內容和span節點必須在輸出中用<para>節點覆蓋。

我寫了以下xsl來獲取此輸出,

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

    <xsl:template match="li[not(descendant::ol)]" >
        <liItem>
            <para>
                <xsl:apply-templates />
            </para>
        </liItem>
    </xsl:template>

    <xsl:template match="li[descendant::ol]" >
        <liItem>
            <para>
                <xsl:apply-templates select="node()[parent::li][following-sibling::ol]"/>
            </para>
        </liItem>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="span">
        <c type="{@style}">
            <xsl:apply-templates/>
        </c>
    </xsl:template>

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

的上面的xsl是唯一的問題是當它具有<ol>內的另一個<ol>項。 我正在努力尋找一種將<para>節點添加到放置在<li><ol>節點之間的文本內容中的方法。

當前輸出如下,

<content>
    <orderedList>
        <liItem>
            <para> List<c type="color: rgb(255,0,255);">The scopeeeee of</c>this project is</para>
        </liItem> List<c type="color: rgb(255,0,255);">The scopeeeee of</c>this project is
        <orderedList>
            <liItem><para>nested list1</para></liItem>
            <liItem><para>nested <c type="color: rgb(255,0,255);">The scope of this project is</c>list1</para></liItem>
            <liItem><para>nested list1</para></liItem>
            <liItem><para>nested list1</para></liItem>
            <liItem><para>nested list1</para></liItem>
        </orderedList>
        <liItem><para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para></liItem>
        <liItem><para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para></liItem>
    </orderedList>
</content>

誰能建議我一種方法,如何修改我的代碼以獲得預期的輸出。

如果ol元素總是要放在li元素中的文本之后,則可以將模板更改為此

<xsl:template match="li[descendant::ol]" >
    <liItem>
        <para>
            <xsl:apply-templates select="node()[following-sibling::ol]"/>
        </para>
    </liItem>
    <xsl:apply-templates select="ol"/>
</xsl:template>

也許是這樣,如果您實際上想要在liItem使用ol元素,但在para中則不需要

<xsl:template match="li[descendant::ol]" >
    <liItem>
        <para>
            <xsl:apply-templates select="node()[following-sibling::ol]"/>
        </para>
        <xsl:apply-templates select="ol"/>
    </liItem>
</xsl:template>

無論哪種情況,您都可以將匹配li的兩個模板合並為一個模板。 像這樣:

<xsl:template match="li" >
    <liItem>
        <para>
            <xsl:apply-templates select="node() except ol"/>
        </para>
        <xsl:apply-templates select="ol"/>
    </liItem>
</xsl:template>

另外,如果您想在一個列表項中處理多個ol元素,或者如果在ol元素之后也有文本,則可以使用xsl:for-each-group

<xsl:template match="li" >
    <liItem>
        <xsl:for-each-group select="node()" group-adjacent="boolean(self::ol)">
            <xsl:choose>
                <xsl:when test="current-grouping-key() or not(normalize-space())">
                    <xsl:apply-templates select="current-group() "/>
                </xsl:when>
                <xsl:otherwise>
                    <para>
                        <xsl:apply-templates select="current-group() "/>
                    </para>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each-group>
    </liItem>
</xsl:template>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM