Как изменить текст в элементе, используя xsl - PullRequest
3 голосов
/ 14 апреля 2009

Как применить изменения к тексту в элементе, не теряя его дочерние элементы.

Например:

У меня есть этот xml, который я хотел бы применить к тексту внутри элемента "p" ....

<section>
    <p >Awesome LO</p>
    <p >
        Begin with an interesting fact, thought-provoking
        <keyword>question</keyword>
        <context>
            <p type="Key Words Head">Banana</p>
            <p type="Key Words">A tasty treat to eat any time, and good with ice cream – a banana split.</p>
        </context>, or a one sentence scenario to illustrate why the learning object (content) is important.
    </p>
    <p >
        Begin with a definition, if required. Then, provide an example by example view.
    </p>
</section>

Так что мой xsl выглядит так ...

<xsl:template match="p">
    <xsl:copy>
        <xsl:call-template name="widont-title">
            <xsl:with-param name="text" select="text()" />
        </xsl:call-template>
    </xsl:copy>
</xsl:template>

Проблема в том, что при этом я теряю "ключевое слово", "контекст" и другие элементы внутри "p". Кто-нибудь может указать мне какие-либо подсказки? Спасибо!

<!-- this method puts a non breaking space in the last word of a 'p' if its less than 5 characters-->
<xsl:template name="widont-title">
    <xsl:param name="temp"/>
    <xsl:param name="text"/>
    <xsl:param name="minWidowLength" select="5"/>

    <xsl:choose>
        <xsl:when test="contains($text, ' ')">
            <xsl:variable name="prev" select="substring-before($text,' ')"/>
            <xsl:variable name="before" select="concat($temp,' ',$prev)"/>
            <xsl:variable name="after" select="substring-after($text, ' ')"/>

            <xsl:choose>
                <xsl:when test="contains($after, ' ')">
                    <xsl:call-template name="widont-title">
                        <xsl:with-param name="temp" select="$before"/>
                        <xsl:with-param name="text" select="$after"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:when test="not(contains($after, ' ')) and string-length(translate($after,'`~!@#$%^\*()-_=+\\|]}[{;:,./?&lt;&gt;','')) &lt; $minWidowLength">

                    <xsl:value-of select="concat($before, '&#160;', $after)" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="concat($before, ' ', $after)" />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

1 Ответ

5 голосов
/ 14 апреля 2009

Непонятно, что делает шаблон widont-title и правильно ли он реализован (выглядит немного сложнее), , но проблема в том, что этот шаблон также применяется -вскоре, не оставляя никаких возможностей для обработки элементов p.

Решение (с использованием шаблона идентификации и переопределением его для p/text() узлов) очень простое :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="p/text()">
        <xsl:call-template name="widont-title">
            <xsl:with-param name="text" select="." />
        </xsl:call-template>
    </xsl:template>

         <!-- "widont-title" template omitted for brevity -->

</xsl:stylesheet>

когда указанное преобразование применяется к предоставленному документу XML, дочерние элементы любого элемента p правильно присутствуют в выходных данных .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...