我有一个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</p><p>$2</xsl:text>
</xsl:param>
</xsl:template>
后来这个:
<col name="Model descr.">
<content>
<xsl:text><p></xsl:text>
</content>
<content>
<xsl:value-of select="replace($find_all, $find_return, $replace_return)"/>
</content>
<content>
<xsl:text></p></xsl:text>
</content>
</col>
这里有什么问题?
由于
扬
答案 0 :(得分:1)
你在这里采取了错误的做法。首先,从您向我们展示的片段中,您有一个带参数的模板,但这些参数在该模板的范围内是本地的。如果您尝试在模板外使用这些参数,则无法访问它们。
此外,replace
函数适用于字符串,您无法使用它来创建<p>
之类的新元素。您将在输出中创建的是<p>
的转义值。
另一种方法是使用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体验有限。如你所见。
扬