2015-11-10 2 views
1

У меня есть 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> s может быть внахлест столько раз, сколько требуется, в зависимости от воли писателя.

Когда я обрабатываю данный элемент 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-leveled <MPMEntry>, от корневого элемента?

Также обратите внимание, что мне нужно использовать XPath 1.0.

ответ

1

Вы можете использовать позиционные предикаты на оси предков, имея в виду, что это обратная ось:

<Level1Title> 
    <xsl:value-of select="ancestor::MPMEntry[last()]/title" /> 
</Level1Title> 
<Level2Title> 
    <xsl:value-of select="ancestor::MPMEntry[last() - 1]/title" /> 
</Level2Title> 
Смежные вопросы