在节点之后替换文本

时间:2010-03-24 21:13:44

标签: xslt replace

我正在尝试从此XML中删除“隐藏此数据”,这是使用限定符类型=“noView”进行的

<element version="Local">
   <qualifier name="Public" type="View" /> 
    Good to go 
</element>
<element version="Local">
<qualifier name="Public" type="noView" /> 
     Hide this data
</element>

我正在使用这个XSL

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="@*"/>
       <xsl:apply-templates/>
     </xsl:copy>
   </xsl:template>

<xsl:template match="qualifier">
   <xsl:call-template name="replace-noview" />
 </xsl:template>

<xsl:template name="replace-noview">
  <xsl:param name="text" select="@type"/>

  <xsl:choose>
  <xsl:when test="contains($text, 'noView')">
    <xsl:copy-of select="."/>
    <xsl:text>DELETED</xsl:text>
  </xsl:when>
  <xsl:otherwise>
    <xsl:copy-of select="."/>
  </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

我得到的输出是

<element identifier="ContactName" version="Local">
<qualifier name="Public" type="View" />
Good to go 
</element>
<element identifier="ContactName" version="Local">
<qualifier name="Public" type="noView" />DELETED 
Hide this data 
</element>

我匹配“noView”属性,可以添加“删除”文本。但是,我需要删除以下“隐藏此数据”文本。

我想要的输出是

<element identifier="ContactName" version="Local">
<qualifier name="Public" type="View" />
Good to go 
</element>
<element identifier="ContactName" version="Local">
<qualifier name="Public" type="noView" />
DELETED 
</element>

2 个答案:

答案 0 :(得分:2)

此转换正确生成了所需的结果

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

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

 <xsl:template match="text()
  [preceding-sibling::*[1]/@type='noView']">
  <xsl:text>DELETED</xsl:text>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档(更正为格式良好):

<t>
 <element version="Local">
   <qualifier name="Public" type="View" />
    Good to go
 </element>
 <element version="Local">
 <qualifier name="Public" type="noView" />
     Hide this data
 </element>
</t>

产生了所需的结果

<t>
 <element version="Local">
   <qualifier name="Public" type="View">
</qualifier>
    Good to go
 </element>
 <element version="Local">
 <qualifier name="Public" type="noView">
</qualifier>DELETED</element>
</t>

注意使用Identity规则及其覆盖仅适用于需要特殊处理的文本节点。 使用和覆盖标识规则是最基本的XSLT设计模式之一

答案 1 :(得分:1)

假设元素可以包含多个文本...请尝试以下样式表:

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

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

  <xsl:template match="text()">
    <xsl:choose>
      <xsl:when test="preceding-sibling::*[1][local-name() = 'qualifier' and @type='noView']">
    DELETED
  </xsl:when>
      <xsl:otherwise>
        <xsl:copy-of select="."/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

间距与choose元素中的输出相关。所以它在输出中看起来没问题。

如果元素只包含一个以qualifier为前缀的文本,则样式可以更容易。