xml - (xslt 1.0) 如何用 xml 中所有文本值中的一些字符串替换空格?

标签 xml xslt xslt-1.0

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="'&#x36;'"/> 
    <xsl:choose>
      <xsl:when test="contains(text,'&#x32;')">
        <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/

相关文章:

xslt - <xsl :value-of select = "."/> mean in an xsl file 是什么意思

xml - 如何查找具有相同 child 的节点

xml - xslt 在模板中集成一个 xsl

java - 在 JAXB 中解码期间忽略未定义的元素引用

java - 从 xml 节点获取行号 - java

xml - XSLT 得到一些不需要的值

xml - 使用 xslt/c# 比较两个 xml 文件

xml - 如何使用 XSLT 生成逗号分隔的列表

java - 如何使用 vtd-xml 解析 xml 而无需硬编码 attr 名称?

xml - Xpath/XSLT : How to select attribute of element which has not child with name. ..?