是否可以在XSLT处理期间导航到匹配节点的父节点?

时间:2010-04-01 20:58:18

标签: xml xslt xpath parent

我正在使用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节点,而不是它的父节点。

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

的文件

有什么想法吗?

4 个答案:

答案 0 :(得分:3)

此:

<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>

答案 1 :(得分:1)

如果您已经处理了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:p元素具有指定属性的最近祖先的所有w:sdt元素,第一个模板将用于所有其他w:p元素

答案 2 :(得分:0)

parent::*或简称..怎么样?

答案 3 :(得分:0)

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

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

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

..