在xslt中标识节点后跟另一个节点

时间:2017-09-26 06:08:29

标签: xml xslt xpath

我是xslt的新手。我有这样的xml,

<para>Randomized practice trains adaptability to different tasks, thereby facilitating the transfer to activities of daily life and improving patient’s reactions.<!-- [443] --><link idref="b1781a677a290_443" target="literature"/> Practicing in unpredictable situations promotes and facilitates the development of effective strategies. The neurologic patient needs success in rehabilitation because successfully executed movements cause strategies to be stored in the central nervous system (CNS).<!-- [369] --><link idref="b1781a677a290_369" target="literature"/> Success in executing movements increases motivation, which is also a requirement for mastering new tasks in the future. The therapist’s instructions should not be directed toward performing the movement but the goal or effect of the movement; the task should have an external focus. This would, in turn, lead to improved efficiency of movement, decreased frequency of errors, and greater maximum strength that the patient can generate.<!-- [448] --><link idref="b1781a677a290_448" target="literature"/> <!-- [444] --><link idref="b1781a677a290_444" target="literature"/> <!-- [445] --><link idref="b1781a677a290_445" target="literature"/> <!-- [117] --><link idref="b1781a677a290_117" target="literature"/> <!-- [264] --><link idref="b1781a677a290_264" target="literature"/> All these effects contribute to the movement becoming automatic.</para>

我需要在节点之间添加一个',',如果连续放置几个(后跟另一个节点)。

所以,对于上面的例子xml,输出应该是

<para>Randomized practice trains adaptability to different tasks, thereby facilitating the transfer to activities of daily life and improving patient’s reactions.<!--[443]--><link idref="b1781a677a290_443" target="literature"><dummy cstyle="Superscript">443</dummy></link> Practicing in unpredictable situations promotes and facilitates the development of effective strategies. The neurologic patient needs success in rehabilitation because successfully executed movements cause strategies to be stored in the central nervous system (CNS).<!--[369]--><link idref="b1781a677a290_369" target="literature"><dummy cstyle="Superscript">369</dummy></link> Success in executing movements increases motivation, which is also a requirement for mastering new tasks in the future. The therapist’s instructions should not be directed toward performing the movement but the goal or effect of the movement; the task should have an external focus. This would, in turn, lead to improved efficiency of movement, decreased frequency of errors, and greater maximum strength that the patient can generate.<!--[448]--><link idref="b1781a677a290_448" target="literature"><dummy cstyle="Superscript">448,</dummy></link> <!--[444]--><link idref="b1781a677a290_444" target="literature"><dummy cstyle="Superscript">444,</dummy></link> <!--[445]--><link idref="b1781a677a290_445" target="literature"><dummy cstyle="Superscript">445,</dummy></link> <!--[117]--><link idref="b1781a677a290_117" target="literature"><dummy cstyle="Superscript">117,</dummy></link> <!--[264]--><link idref="b1781a677a290_264" target="literature"><dummy cstyle="Superscript">264</dummy></link> All these effects contribute to the movement becoming automatic.</para>

我尝试编写一个xsl模板来识别连续注释并添加','如下,

<xsl:template match="link">
        <xsl:choose>
            <xsl:when test="@target = 'literature'">
                <xsl:variable name="refCount"><xsl:value-of select="normalize-space(substring-after(@idref, '_'))"/></xsl:variable>
                <xsl:choose>
                    <xsl:when test="empty(node())">
                        <xsl:copy>
                            <xsl:apply-templates select="@*"/>
                            <xsl:element name="dummy">
                                <xsl:attribute name="cstyle">
                                    <xsl:value-of select="'Superscript'"/>
                                </xsl:attribute>
                                <xsl:value-of select="$refCount"/>
                                <xsl:if test="preceding-sibling::*[1][self::link]">
                                    <xsl:text>,</xsl:text> 
                                </xsl:if>
                            </xsl:element>                            
                        </xsl:copy>
                    </xsl:when>               
                    <xsl:otherwise>
                        <xsl:copy>
                            <xsl:apply-templates select="node()|@*"/>
                        </xsl:copy>
                    </xsl:otherwise>
                </xsl:choose>
           </xsl:when> 
    </xsl:choose>

有没有想过纠正这个xpath?

另外,我尝试使用node()方法,如下所示。

<xsl:if test="preceding-sibling::node()[1][self::link]">
    <xsl:text>,</xsl:text> 
</xsl:if>

添加node()时,逗号','未在输出中反映。

<link>代码之间添加','会非常有用。

2 个答案:

答案 0 :(得分:0)

我想你想添加一个逗号,如果第一个兄弟节点(不是注释或空文本节点)是link元素....

<xsl:if test="following-sibling::node()
                 [not(self::comment() | self::text()[not(normalize-space())])]
                 [1][self::link]">

尝试使用此XSLT(我已将其简化,将测试条件移至模板匹配

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

    <xsl:template match="link[@target = 'literature'][empty(node())]">
        <xsl:variable name="refCount"><xsl:value-of select="normalize-space(substring-after(@idref, '_'))"/></xsl:variable>
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <dummy cstyle="Superscript">
                <xsl:value-of select="$refCount"/>
                <xsl:if test="following-sibling::node()[not(self::comment() | self::text()[not(normalize-space())])][1][self::link]">
                    <xsl:text>,</xsl:text> 
                </xsl:if>
            </dummy>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="link" />

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

答案 1 :(得分:0)

以下是for-each-group group-adjacent的尝试:

<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="@* | node()" mode="#all">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" mode="#current"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="para">
        <xsl:copy>
            <xsl:for-each-group select="node()" group-adjacent="boolean(self::comment()[matches(., '^\s*\[[0-9]+\]\s*')] | self::link[@idref] | self::text()[not(normalize-space())])">
                <xsl:apply-templates select="current-group()" mode="adjacent"/>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="link[@idref]" mode="adjacent">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <dummy cstyle="Superscript">
                <xsl:value-of select="substring-after(@idref, '_')"/>
                <xsl:if test="position() ne last()">,</xsl:if>
            </dummy>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>