XSLT: change node inner text

2019-02-16 18:58发布

I need to transform the following xml doc:

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

into this:

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

So, i wrote this XSLT document

<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>

This way, i get the following result:

<?xml version="1.0" encoding="utf-8"?>
<a>
  <b /><c />
  differentText
</a>
<a>
  <b /><c />
  differentText
</a>
<a>
  <b /><c />
  differentText
</a>

The result appears repeated 3 times because 3 matches are being done.. Why? I could i fix it? Thanks

标签: xslt
2条回答
▲ chillily
2楼-- · 2019-02-16 19:33

Exclude the whtespace-only text nodes. Know and use the <xsl:strip-space> instruction.

This transformation:

<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>

when applied to the provided XML document, produces the wanted correct result.

No need for complicated predicates in the match expression of the specific template!

We should be striving for the simplest, shortest, most elegant, most readable, most understandable solution that employs the full power of the language.

Chances are that such a solution will be most understood, most easy to implement and most likely to be optimized by any XSLT processor, resulting in a most efficient implementation.

查看更多
戒情不戒烟
3楼-- · 2019-02-16 19:44

There are three matches, as highlighted by square brackets:

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

You want something like:

<xsl:template match="/a/text()[normalize-space() != '']">
查看更多
登录 后发表回答