如何在xml中的标记嵌套中移回

时间:2009-08-28 09:32:38

标签: xml xslt

解释我的问题的最好方法是给出一个例子xml:

<block>
  <if>
    <trans>
      <trans1>
        <text1>text</text1>
      </trans1>
      <trans1>
        <text1>text</text1>
      </trans1>
    </trans>
    <if>
      <trans>
        .......
      </trans>
    </if>
  </if>
</block>

因此要捕获其中的所有数据,您可以执行(xsl:for-each select =“block / if / trans / trans1”)...获取数据。 现在我想退出trans和trans1所以我可以进入“block / if / if”...

我知道我可以单独执行for-each但是我需要在表格的一个单元格中获取所有这些数据,因此您需要为每个单元格执行嵌套操作但我不知道您是否可以/如果有可能后退一点吗?

有谁知道这是否可能,如果可以,怎么做?

2 个答案:

答案 0 :(得分:1)

  

所以要捕获其中的所有数据,你会做一个(xsl:for-each select =“block / if / trans / trans1”)

不,我不会。我几乎从不使用 - 每个。我会这样做:

<xsl:apply-templates select="block/if/trans/trans1"/>
  

现在我想退出trans和trans1所以我可以进入“block / if / if”..

如果trans1是上下文节点,则可以使用祖先轴到达其第一个if祖先:

<xsl:template match="trans1">
   <xsl:apply-templates select="ancestor::if[1]"/>
</xsl:template>
但是,你真的不清楚你在问什么。您是否正在尝试展平层次结构,并为每个block创建一个HTML表格,每个tr if td text1 if每个<xsl:template match="block"> <table> <xsl:apply-templates select=".//if"/> </table> </xsl:template> <xsl:template match="if"> <tr> <xsl:apply-templates select="trans/trans1/text1"/> </tr> </xsl:template> <xsl:template match="text1"> <td> <xsl:value-of select="."/> </td> </xsl:template> 下面的元素?如果是这样,那就需要这样的事情:

text1

在上面的示例中,我假设您知道if后代的确切路径,如示例所示。

如果您不知道从text1元素到.//text1 后代的确切路径,那就更难了。你不想使用

text1

因为它将选择所有 if后代,包括后代text1元素的后代。这将导致相同的td元素在输出中生成多个if元素 - 每个text1 | .//*[name() != 'if']//text1 元素一个元素是它的后代。为避免这种情况,您需要使用如下模式:

text1

这将选择任何直接text1子项,以及任何if后代,这些后代本身不是后代text1元素的后代。

实际上,这也有效:

.// text1 [ancestor :: if [1] = current()]

找到所有if个后代,其第一个if祖先向上移动祖先链,是当前{{1}}元素。这比第一个示例更容易理解,但第一个示例可能表现更好,除非XSLT处理器非常智能。

答案 1 :(得分:0)

不完全清楚你需要做什么。我想您希望从/block/if 所有 trans/trans1元素中检索这些元素,无论它们位于哪个if。在此基础上尝试: -

 <xsl:for-each select="block/if//trans/trans1">

请注意,路径中的//descendants::的简写,并会在父trans下方的任意深度选择if的任何出现。