我如何检查节点的至少一个后代是否具有文本内容



我有一个看起来像

的XML
<xml>
    <grandparent>
        <parent>
            <child1/>
            <child2/>
            <child3>value</child3>
        </parent>
    </grandparent>
</xml>

,如果至少一个父母的后代具有Value

,我需要应用某些模板

搜索本网站后,我提出了一个代码

<xsl:if test="grandparent/parent//* != '' ">
    <xsl:apply-templates select="parent"/>
</xsl:if>

但它不起作用。当我运行这个时,什么都没有。申请模板本身确实有效,因此问题不是模板我在做什么错?

如果至少一个父母的后代,我需要应用某些模板 有值

搜索本网站后,我提出了一个代码

<xsl:if test="grandparent/parent//* != '' ">
    <xsl:apply-templates select="template1"/>
</xsl:if>

但不起作用。

分析

  1. 使用<xsl:apply-templates>指令应用模板时,无法指定任何模板名称(并且通常未命名模板(。select属性预计将包含的是XPath Expresion,该XPATH返回节点集(XSLT 3.0中的序列(,并带有必须应用模板的节点。
  2. 因此,select="template1"表示不是应用名为" Template1"的模板,而是将模板应用于当前节点的任何子元素,称为template1,因为在提供的XML文档中有名为template1的NO元素,什么都没有选择,也没有任何应用模板。这解释了报告的行为

您可能要使用<xsl:call-template name="template1">,但是在XSLT中打电话给命名模板通常不是一个好习惯。

另外,您尚未指定应应用或调用模板时当前节点是什么。

解决方案

让我们假设当前节点是XML文档中的最高节点。

以下是一种仍然使用<xsl:apply-templates>的转换,但仅指定XSLT处理器选择要执行的模板时要使用的模板模式:

<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="grandparent">
    <xsl:apply-templates mode="template1" select="parent[*//text()]"/>
  </xsl:template>
  <xsl:template match="parent" mode="template1">
    Template in mode template1 Applied
  </xsl:template>
</xsl:stylesheet>

将这种转换应用于提供的XML文档时:

<xml>
    <grandparent>
        <parent>
            <child1/>
            <child2/>
            <child3>value</child3>
        </parent>
    </grandparent>
</xml>

产生了通缉结果(显示模板已选择进行执行和执行(:

Template in mode template1 Applied

现在,让我们用修改的XML文档对此进行测试,其中grandparent/parent的孩子没有文本节点孩子:

<xml>
    <grandparent>
        <parent>
            <child1/>
            <child2/>
            <child3></child3>
        </parent>
    </grandparent>
</xml>

当我们在此XML文档上应用相同的转换时,不会产生输出 - 完全按照所需的方式。

最新更新