EDIT: [it started with character replacement and I ended up with discovering string replacements with help of Dimitre Novatchev and Roland Bouman
我认为示例代码足以解释需求..
这是示例 XML:
<root>
<node1>text node</node1>
<node2>space between the text</node2>
<node3> has to be replaced with $</node3>
</root>
这是我期待的输出:
<root>
<node1>text$node</node1>
<node2>space$between$the$text</node2>
<node3>$has$to$be$replaced$with$$</node3>
</root>
我曾尝试编写未显示所需输出的 XSLT 代码..
这是代码:
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()[.!='']">
<xsl:call-template name="rep_space">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="rep_space">
<xsl:param name="text"/>
<xsl:variable name="temp" select="'6'"/>
<xsl:choose>
<xsl:when test="contains(text,'2')">
<xsl:call-template name="rep_space">
<xsl:with-param name="text" select="concat((concat(substring-before(text,' '),temp)),substring-after(text,' '))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
translate(., ' ', '$')function works .. but not to the satisfactory extent .. my questions are .. what if it is a string instead of character? I mean, suppose I am intended to replace ' ' with "%20"? And one more case, What if the input XML isn't "Pretty Print XML", then all the space appearing in XML are replaced with '$' ..
Pretty print XML 是具有适当缩进的文件,(通常我的输入 XML 从来没有这个)例如:
多一个节点 这是@低层
可以观察到,<new> <test>
之前没有“空格字符”节点,但它们实际上是正确缩进的,(使用 altova XMLSPY 我们可以在编辑菜单中给出一个简单的命令.. 使任何 XML 文件成为“ pretty-print XML”)..
在下面的例子中..
<new>
<test>one more node</test>
<test2>
<child>this is @ lower level</child>
</test2>
</new>
所有开始标签前都有空格字符.. <child>
标签前面的空格多于 <test2>
节点..
对于第二个示例 xml .. 所有空格字符都替换为“%20
”.. 因此输出将是..
<new>
%20%20<test>one%20more%20node</test>
%20%20<test2>
%20%20%20%20<child>this%20is%20@%20lower%20level</child>
%20%20</test2>
</new>
当然不是预期的..
The solutions posted by Dimitre Novatchev and Roland Bouman can also replace a string by another string, by modifying the parameters passed to the template being called.
That was great learning @Dimitre, @Roland, I am really thankful and grateful to you guys ..
regards,
infant pro.
最佳答案
应Roland的意愿,这是一个尾递归解决方案:
<xsl:template name="replace">
<xsl:param name="ptext"/>
<xsl:param name="ppattern"/>
<xsl:param name="preplacement"/>
<xsl:choose>
<xsl:when test="not(contains($ptext, $ppattern))">
<xsl:value-of select="$ptext"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($ptext, $ppattern)"/>
<xsl:value-of select="$preplacement"/>
<xsl:call-template name="replace">
<xsl:with-param name="ptext"
select="substring-after($ptext, $ppattern)"/>
<xsl:with-param name="ppattern" select="$ppattern"/>
<xsl:with-param name="preplacement" select="$preplacement"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
请注意,递归调用是模板中的最后一条指令——这就是使它成为尾递归的原因。尾递归的特性允许智能 XSLT 处理器(例如 Saxon 或 .NET XslCompiledTransform)优化代码,用简单的迭代代替递归。
即使调用的“嵌套”数以百万计,此类代码也不会以堆栈溢出异常结束,而非尾递归(和递归)代码通常会在大约 1000 次嵌套的深度引发此堆栈溢出调用(这实际上取决于可用内存量)。
如果 XSLT 处理器不够“智能”怎么办?是否有另一种技术可以避免深层递归调用堆栈溢出,适用于每个 XSLT 处理器?
在一个单独的问题中问我,我可能会告诉你:)
关于xml - (xslt 1.0) 如何用 xml 中所有文本值中的一些字符串替换空格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2318118/