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

XSLT在嵌套在非所需元素中时选择所需元素

  •  0
  • chernevik  · 技术社区  · 15 年前

    当要提取的节点有时是要忽略的嵌套节点时,我将使用什么XSLT来提取一些要输出的节点,而忽略其他节点?

    <alpha_top>This prints.
      <beta>This doesn't.
        <alpha_bottom>This too prints.</alpha_bottom>
      </beta>
    </alpha_top>
    

    我想要一个生成以下内容的转换:

    <alpha_top>This prints.
        <alpha_bottom>This too prints.</alpha_bottom>
    </alpha_top>
    

    answer 显示如何基于元素标记名中的字符串选择节点。

    4 回复  |  直到 7 年前
        1
  •  0
  •   Darrel Miller    15 年前

    下面的样式表适用于您的特定情况,但我怀疑您正在寻找更通用的样式表。我也相信有一个更简单的方法。

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:apply-templates select="alpha_top"></xsl:apply-templates>
    </xsl:template>
    
    <xsl:template match="alpha_top">
        <xsl:copy>
        <xsl:apply-templates select="beta/alpha_bottom|text()"></xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="*|text()">
        <xsl:copy>
            <xsl:apply-templates select="*|text()"></xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
    </xsl:stylesheet>
    
        2
  •  0
  •   Darrel Miller    15 年前

    好的,这里有一个更好的方法

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

        3
  •  0
  •   Nic Gibson    15 年前

    我认为,一旦您对XSLT遍历的工作原理有了合理的了解(希望我在您的另一个问题中回答了这个问题),这就变得非常简单了。

    你有几个选择如何做到这一点。Darrell Miller的回答表明,您必须处理整个文档,并去掉您不感兴趣的元素。这是一种方法。

    在进一步讨论之前,我得到的印象是,您可能无法完全“理解”XSLT中的上下文概念。这很重要,会让你的生活更简单。在XSLT中,任何时候都只有一个上下文节点。这是当前正在“处理”的节点(元素、属性、注释等)。在名为via xsl:select的模板中,选择的节点是上下文节点。因此,考虑到您的xml:

    <alpha_top>This prints.
      <beta>This doesn't.
        <alpha_bottom>This too prints.</alpha_bottom>
      </beta>
    </alpha_top>
    

    <xsl:apply-templates select='beta'/>
    

    <xsl:template match='beta'>...</xsl:template>
    

    因此,当您以以下内容开始样式表时:

    <xsl:template match='/'>
        <xsl:apply-templates select='alpha_top'/>
    </xsl:apply-templates>
    

    现在,在顶层模板中,您可能决定只处理alpha_底部节点。然后你可以写一个声明,比如:

    <xsl:template match='/>
        <xsl:apply-templates select='//alpha_top'/>
    </xsl:template>
    

    这将遍历树并选择所有alpha_顶部元素,而不选择其他元素。

    或者,您可以处理所有元素,只需忽略beta节点的内容:

    <xsl:template match='beta'>
        <xsl:apply-templates/>
    </xsl:template>
    

    (正如我在给您的另一封回复中提到的,没有选择属性的xsl:apply模板与使用相同 选择 '*).

    这将忽略beta节点的内容,但会处理它的所有子节点(假设您有模板)。

    因此,忽略输出中的元素基本上就是在select属性中使用正确的xpath语句。当然,您可能需要一个好的xpath教程:)

        4
  •  0
  •   Tomalak    15 年前

    <xsl:template match="alpha_top|alpha_bottom">
      <xsl:copy>
        <xsl:value-of select="text()" />
        <xsl:apply-templates />
      </xsl:copy>
    </xs:template>
    
    <xsl:template match="text()" />
    

    这与示例中的空白行为不同,但这可能是不相关的。