XSLT:更改节点内部文本

9

我需要转换以下XML文档:

<a>
  <b/>
  <c/>
   myText
</a>

转化为:

<a>
  <b/>
  <c/>
   differentText
</a>

所以,我写了这个XSLT文档。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" version="1.0" omit-xml-declaration="no" />

  <xsl:template match="/a/text()">
    <a>
      <b/>
      <c/>
      differentText
    </a>
</xsl:template>
</xsl:stylesheet>

这样,我得到了以下结果:
<?xml version="1.0" encoding="utf-8"?>
<a>
  <b /><c />
  differentText
</a>
<a>
  <b /><c />
  differentText
</a>
<a>
  <b /><c />
  differentText
</a>

结果出现了三次重复,因为进行了3次匹配。为什么?我该怎么解决?谢谢。

好问题(+1)。请看我的答案,提供了更好、更简单的解决方案,不需要在特定模板的匹配表达式中使用任何谓词。 - Dimitre Novatchev
2个回答

10

排除仅包含空格的文本节点。了解并使用<xsl:strip-space>指令。

这个转换:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

 <xsl:template match="a/text()">
   <xsl:text>Diferent text</xsl:text>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时,可以产生所需的正确结果

在特定模板的匹配表达式中无需复杂的谓词

我们应该追求最简单、最短、最优雅、最易读、最易懂的解决方案,并发挥语言的全部威力。

很可能这样的解决方案会被大多数XSLT处理器最好地理解、最容易实现和最有可能进行优化,从而得到最有效的实现。


顺便说一句,我不认为[normalize-space() != '']是一个特别复杂的谓词。 ;) - Tomalak
@Tomalak:我们应该追求最简单、最短、最优雅、最易读、最易懂的解决方案,同时充分利用语言的全部功能。很有可能这样的解决方案会被大多数XSLT处理器所理解、实现和优化,从而得到最高效的实现。 :) - Dimitre Novatchev

7

这里有三个匹配项,用方括号标出:

<a>[
  ]<b/>[
  ]<c/>[
   myText
]</a>

你需要的是这样的东西:
<xsl:template match="/a/text()[normalize-space() != '']">

正如我的回答所示,在匹配表达式中不需要谓词。 :) - Dimitre Novatchev
4
@Dimitre: 我知道这一点。我的回答对现有代码进行了最小可能的更改。它是基于一个假设,即实际代码更为复杂,而 <xsl:strip-space> 可能会在其他地方产生副作用。 - Tomalak
@Tomalak:假设OP没有说的事情通常会使解决方案不够优化,更难理解,甚至令人困惑。如果我们这样做,最终可能会告诉我们所有关于XSLT的知识--“以防万一...” :) - Dimitre Novatchev
@Dimitre:我们在这里是为了向人们传授我们对XSLT的了解。而在这个特定的情况下,你比我做得更多。;) 不要误会,你的解决方案更符合“按照书本来”的标准。我的解决方案只需要改变一行代码。 - Tomalak
@所有人。我选择了Dimitre的答案,因为当我有多个模板时,我只需要进行一次更改。但我真的很感激Tomalak的回答,他说我的原始代码更加复杂是正确的。当我发布问题时,我总是简化以帮助读者更快地理解它。现在我建议你看看这个链接:http://stackoverflow.com/questions/2899484/xslt-add-node-inner-text :) - Nabo
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接