代码之家  ›  专栏  ›  技术社区  ›  Guillaume

如何从文档中删除<b/>

  •  1
  • Guillaume  · 技术社区  · 16 年前

    我试图有一个XSLT,它复制了大多数标签,但删除了空标签” <b/> 标签。也就是说,它应该按原样复制 <b> </b> “或” <b>toto</b> “但完全删除” <b/> ".

    我认为模板看起来像:

    <xsl:template match="b">
      <xsl:if test=".hasChildren()">
        <xsl:element name="b">
          <xsl:apply-templates/>
        </xsl:element>
      </xsl:if>
    </xsl:template>
    

    当然,“ hasChildren() “部分不存在……有什么想法吗?

    7 回复  |  直到 16 年前
        1
  •  3
  •   Community CDub    8 年前

    dsteinweg 让我走上正轨。..我最终做了:

    <xsl:template match="b">
        <xsl:if test="./* or ./text()">
            <xsl:element name="b">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:if>
    </xsl:template>
    
        2
  •  3
  •   Dimitre Novatchev    16 年前

    这种转换忽略任何<b>没有任何节点子级的元素。在此上下文中,节点是指元素、文本、注释或处理指令节点。

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes"/>
        <xsl:template match="node()|@*">
          <xsl:copy>
             <xsl:apply-templates select="node()|@*"/>
          </xsl:copy>
        </xsl:template>
    
        <xsl:template match="b[not(node()]"/>
    </xsl:stylesheet>

    请注意,这里我们使用了最基本的XSLT设计模式之一——使用 identity transform 并为特定节点覆盖它。

    覆盖模板将仅为名为“b”且没有子节点的节点选择。此模板为空(没有任何内容),因此其应用程序的效果是忽略/丢弃匹配节点,并且不会在输出中再现。

    这种技术非常强大,广泛用于此类任务,也用于重命名、更改内容或属性、向任何可以匹配的特定节点添加子节点或兄弟节点(除命名空间节点外的任何类型的节点都可以用作<xsl:template/>的“match”属性中的匹配模式);

    希望这能有所帮助。

    干杯,

    迪米特尔·诺瓦切夫

        3
  •  2
  •   Darren Steinweg    16 年前

    我想知道这是否可行?

    <xsl:template match="b">
      <xsl:if test="b/text()">
        ...
    
        4
  •  1
  •   Vincent Ramdhanie    16 年前

    看看这是否可行。

    <xsl:template match="b">
      <xsl:if test=".!=''">
        <xsl:element name="b">
         <xsl:apply-templates/>
        </xsl:element>
      </xsl:if>
    </xsl:template>
    
        5
  •  1
  •   samjudson    16 年前

    另一种选择是采取以下措施:

    <xsl:template match="b[not(text())]" />
    
    <xsl:template match="b">
      <b>
        <xsl:apply-templates/>
      </b>
    </xsl:template>
    
        6
  •  1
  •   James Sulak    16 年前

    你可以把所有的逻辑放在谓词中,并设置一个模板来只匹配你想要的,然后删除它:

    <xsl:template match="b[not(node())] />
    

    这假设您稍后在转换中有一个身份模板,听起来像是这样。这将自动复制任何带有内容的“b”标签,这就是您想要的:

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

    编辑: 现在像Dimitri一样使用node(),如下所示。

        7
  •  0
  •   Tim C    16 年前

    如果您有权更新原始XML,可以尝试使用 xml:space=保留 论根元素

    <html xml:space="preserve">
    ...
    </html>
    

    这样,空的空间<b></b>标签被保留,因此可以与<b/>在XSLT中。

    <xsl:template match="b">
       <xsl:if test="text() != ''">
       ....
       </xsl:if>
    </xsl:template>