【问题标题】:Is it possible to navigate to the parent node of a matched node during XSLT processing?在 XSLT 处理期间是否可以导航到匹配节点的父节点?
【发布时间】:2010-04-01 20:58:18
【问题描述】:

我正在处理一个 OpenXML 文档,使用一些 XSLT 处理主文档部分。

我通过

选择了一组节点
<xsl:template match="w:sdt">
</xsl:template>

在大多数情况下,我只需将匹配的节点替换为其他内容即可。

但是,在某些情况下,我需要替换的不是匹配的 w:sdt 节点,而是最接近的 w:p 祖先节点(即包含 sdt 节点的第一个段落节点)。

诀窍在于,用于决定一个或另一个的条件是基于从 sdt 节点的属性派生的数据,所以我不能使用典型的 xslt xpath 过滤器。

我正在尝试做这样的事情

<xsl:template match="w:sdt">
  <xsl:choose>
    <xsl:when test={first condition}> 
        {apply whatever templating is necessary}
    </xsl:when> 
    <xsl:when test={exception condition}> 
      <!-- select the parent of the ancestor w:p nodes and apply the appropriate templates -->
      <xsl:apply-templates select="(ancestor::w:p)/.." mode="backout" />
    </xsl:when> 
  </xsl:choose> 
</xsl:template>


<!-- by using "mode", only this template will be applied to those matching nodes
     from the apply-templates above -->
<xsl:template match="node()" mode="backout">
  {CUSTOM FORMAT the node appropriately}
</xsl:template>

这整个概念有效,但无论我尝试了什么,它总是将 CUSTOM FORMAT 模板中的格式应用于 w:p 节点,而不是它的父节点。

这几乎就像您无法从匹配节点引用父级一样。也许你不能,但我没有找到任何文档说你不能

有什么想法吗?

【问题讨论】:

    标签: xml xslt xpath parent


    【解决方案1】:

    这个:

    <xsl:apply-templates select="(ancestor::w:p)/.." mode="backout" />
    

    将找到所有作为上下文节点祖先的w:p 元素,并将模板应用于每个元素的父元素。在我看来,您可能想做的只是找到最近的祖先,例如:

    <xsl:apply-templates select="ancestor::w:p[1]/.." mode="backout" />
    

    但是您在此处描述的内容应该以某种方式起作用。您可能应该通过将 backout 模板替换为更具诊断性的模板来验证您认为正在发生的事情实际上正在发生的事情,例如:

    <xsl:template match="node()" mode="backout">
       <xsl:text>backout matched a </xsl:text>
       <xsl:value-of select="name()"/>
       <xsl:text> element.</xsl:text>
    </xsl:template>
    

    【讨论】:

      【解决方案2】:

      parent::* 或简单的.. 怎么样?

      【讨论】:

        【解决方案3】:

        如果已经处理了w:p节点,遇到后代w:sdt节点时不能回溯,替换为祖先所做的处理。在处理w:p节点本身时,首先需要确定是否进行自定义格式化。

        一种方法是覆盖 w:p 节点的模板,以便您拥有

        • w:p 节点的通用模板
        • w:p 节点的覆盖模板,它是特例 w:sdt 节点的最近祖先

        要确定w:p 是否是最近的祖先,您可以使用xsl:key

        例子:

        <xsl:key name="sdt-descendants" 
                 match="w:sdt[@someAttribute='someValue']"
                 use="generate-id(ancestor::w:p[1])"/>
        
        <xsl:template match="w:p">
            <!-- General behavior -->
        </xsl:template>
        
        <xsl:template match="w:p[key('sdt-descendants', generate-id())]">
            <!-- Specific behavior if the element is the closest w:p ancestor to a 
                 descendant w:sdt element matching the provided criteria. -->
        </xsl:template>
        

        第二个模板将用于与具有指定属性的w:sdt元素最接近的所有w:p元素,而第一个模板将用于所有其他w:p元素。

        【讨论】:

          【解决方案4】:

          在子代之后处理父代的方法对于 XSLT 应用程序是不正确的

          请提供一个有效的(但尽可能最小的)示例,其中包含源 XML 文档和实际的 xslt 样式表。另外,解释应该产生什么输出以及输出是如何从源 XML 文档派生的。

          也就是说,当前节点的父节点是通过这个简单的 XPath 表达式选择的

          ..
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-04-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多