XSLT用<p> </p> <p>替换\ n

时间:2016-12-19 08:33:08

标签: xml xslt line-breaks

我有一个XML,在一个节点中有一堆带有几个段落的文本。我需要将{n替换为</p><p>,所有文本部分的开头都会有一个<p>,而在XSLT定义中会有一个</p>

我试过这个但它在Saxon中给我一个错误:变量find_all尚未声明(或其声明不在范围内)

<xsl:template match="/csv/row/col[17]">
    <xsl:param name="find_all">
        <xsl:value-of select="."/>
    </xsl:param>
    <xsl:param name="find_return">
        <xsl:text>(.*)\n(.*)</xsl:text>
    </xsl:param>
    <xsl:param name="replace_return">
        <xsl:text>$1&lt;/p&gt;&lt;p&gt;$2</xsl:text>
    </xsl:param>
</xsl:template>

后来这个:

<col name="Model descr.">
    <content>
        <xsl:text>&lt;p&gt;</xsl:text>
    </content>
    <content>
        <xsl:value-of select="replace($find_all, $find_return, $replace_return)"/>
    </content>
    <content>
        <xsl:text>&lt;/p&gt;</xsl:text>
    </content>
</col>

这里有什么问题?

由于

2 个答案:

答案 0 :(得分:1)

你在这里采取了错误的做法。首先,从您向我们展示的片段中,您有一个带参数的模板,但这些参数在该模板的范围内是本地的。如果您尝试在模板外使用这些参数,则无法访问它们。

此外,replace函数适用于字符串,您无法使用它来创建<p>之类的新元素。您将在输出中创建的是&lt;p&gt;的转义值。

另一种方法是使用tokenize函数,根据换行符拆分文本,并迭代每个项目,将其包装在新的<p>标记中。

试试这个XSLT

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

    <xsl:template match="text()" priority="2">
        <xsl:for-each select="tokenize(., '\n')[normalize-space()]">
            <p>
                <xsl:value-of select="." />
            </p>            
        </xsl:for-each>
    </xsl:template>

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

答案 1 :(得分:0)

好好再看一下这个我会更进一步。我的进程涉及一个XSLT,它将节点<row>拆分为单个XML文件。在这个较小的XML文件上运行tokenize函数会更容易。

但我只想在这个XML的节点上标记文本,我该如何选择那个。我发现了这个:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/excel-row/col">
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()">
    <xsl:for-each select="tokenize(.,'\n')">
        <xsl:sequence select="."/>
        <xsl:if test="not(position() eq last())">
            <br />
        </xsl:if>
    </xsl:for-each>
</xsl:template>

xml节点如下所示:

<col name="Model descr.">Some text in first paragraph.
More text in second paragraph.
And then a third paragraph with more text.

然后我们有最后一段。

那么如何选择节点col name="Model descr.">

感谢任何帮助,我的XSLT体验有限。如你所见。