1

如果元素值是特定的字符串值,我只想清除元素值

输入xml

<A>
  <B>
    <C>BOLD</C>
  </B>
</A>

期望的输出

<A>
  <B>
    <C/>
  </B>
</A>

我的 xslt 看起来像下面这不起作用它只会清除所有内容

 <xsl:template match="A/B/C/text()">
    <xsl:if test="text()='BOLD'">
      <xsl:text></xsl:text>
    </xsl:if>
  </xsl:template>

<!--Copy the rest of the document as it is-->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

请帮忙谢谢

4

3 回答 3

1

解决此问题的另一种方法是:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

  <xsl:template match="*[text()='BOLD']">
    <xsl:copy/>
  </xsl:template>

</xsl:stylesheet> 
于 2013-11-01T07:34:52.793 回答
1

如果文本不是 ,则第一个模板中的逻辑不会输出任何内容"BOLD",因此如果文本是粗体,则它不会吐出任何内容,否则它仍然不会吐出任何内容。此外,text()节点不会有自己的文本。

所以,用这个替换第一个模板,它应该可以正常工作。

  <xsl:template match="A/B/C/text()">
    <xsl:if test="not(.='BOLD')">
        <xsl:copy/>
    </xsl:if>
  </xsl:template>

并应用于此:

<A>
  <B>
    <C>Bold</C>
    <C>BOLD</C>
    <C>Italic</C>
  </B>
</A>

给出了这个:

<A>
  <B>
    <C>Bold</C>
    <C/>
    <C>Italic</C>
  </B>
</A>
于 2013-10-31T23:58:12.740 回答
1

鉴于您已经开始使用身份模板,因此实际上不需要使用显式xsl:if,只需将条件放在空模板的匹配表达式中:

<xsl:template match="A/B/C/text()[. = 'BOLD']"/>

A/B/C不在或内容不在的文本节点BOLD将由身份模板处理并照常复制。

在匹配表达式中使用的警告text()是,它意味着模板一次只查看一个文本节点,并且只查看直接位于C元素内部的文本。如果C可以有其他内容,你会得到一些奇怪的边缘情况:

<C>BOLD<br/></C> --> <C><br/></C>
<C><b>B</b>OLD</C> --> unchanged
<C><b>BOLD</b></C> --> unchanged

如果您想将 C 下的全文视为一个单元而不考虑子元素,那么您需要更像

<xsl:template match="C[. = 'BOLD']">
  <C/>
</xsl:template>

不用说text()。这将清除我上面的​​所有三个示例。

于 2013-11-01T08:48:33.677 回答