如何从根元素中检索元素祖先?

时间:2015-11-10 14:29:48

标签: xml xslt xpath

我有一个以这种方式构建的XML文档:

<?xml version="1.0"?>
<MPM>
  <MPMEntry>
    <title>Title 1</title>
    <MPMEntry>
      <!-- Nest any number of MPMEntry ... -->
      <title>Title 1.1</title>
      <MPMEntry>
        <!-- Nest any number of MPMEntry ... -->
        <title>Title 1.1.1</title>
        <MPMEntry>
           <title>Title 1.1.1.1</title>
           <DM id="dm_1111a">
             <title>DM title a</title>
             <para>and so on</para>
           </DM>
           <DM id="dm_1111b">
             <title>DM title b</title>
             <para>and so on</para>
           </DM>
        </MPMEntry>
      </MPMEntry>
    </MPMEntry>
    <MPMEntry>
       <title>Title 1.2</title>
      <MPMEntry>
         <title>Title 1.2.1</title>
        <MPMEntry>
           <title>Title 1.2.1.1</title>
           <DM id="dm_1211">
             <title>DM title m</title>
             <para>and so on</para>
           </DM>
        </MPMEntry>
      </MPMEntry>
    </MPMEntry>
  </MPMEntry>
  <MPMEntry>
     <title>Title 3</title>
  </MPMEntry>
  <!-- ... and so on ... -->
</MPM>

根据作者的意愿,<MPMEntry>可以根据需要多次叠加。

当我处理给定的DM元素(这是XML结构的最终级别)时,我需要能够检索第一级和第二级<MPMEntry>(来自根目录) XML文档)它嵌套的标题。

即,对于<DM id="dm_1111a">,我需要检索标题1 标题1.1 。对于<DM id="dm_1111a">,我需要检索标题1 标题1.2

目前,我使用的是以下XPath(1.0)表达式:

  • 代表第一个<MPMEntry>ancestor::MPMEntry[parent::MPM]/title
  • 代表第二个<MPMEntry>ancestor::MPMEntry[parent::MPMEntry/parent::MPM]/title

这是一个简单的XSL样式表(参见http://xsltransform.net/gWvjQf9):

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output method="xml" encoding="UTF-8" indent="yes" />


    <xsl:template match="MPM">
        <xsl:copy>
            <xsl:apply-templates select="descendant::DM" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="DM">
        <Level1Title>
            <xsl:value-of select="ancestor::MPMEntry[parent::MPM]/title" />
        </Level1Title>
        <Level2Title>
            <xsl:value-of select="ancestor::MPMEntry[parent::MPMEntry/parent::MPM]/title" />
        </Level2Title>

        <xsl:copy-of select="."/>

    </xsl:template>

</xsl:stylesheet>

我的问题是:是否有更简单或更直接的方法来检索所需信息?是否有更通用的可能性(我很可能需要获得第三级,依此类推) - 如果可能的话,使用数字索引,告诉我从根元素获得nth-level <MPMEntry>

请注意,我需要使用XPath 1.0。

1 个答案:

答案 0 :(得分:1)

您可以在祖先轴上使用位置谓词,请记住它是一个反向轴:

<Level1Title>
    <xsl:value-of select="ancestor::MPMEntry[last()]/title" />
</Level1Title>
<Level2Title>
    <xsl:value-of select="ancestor::MPMEntry[last() - 1]/title" />
</Level2Title>