Можно ли перейти к родительскому узлу соответствующего узла во время обработки XSLT? - PullRequest
1 голос
/ 02 апреля 2010

Я работаю с документом 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 ]

3 голосов
/ 02 апреля 2010

Это:

<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 голос
/ 02 апреля 2010

Если вы уже обработали узел w:p, вы не сможете вернуться назад, когда встретите дочерний узел w:sdt, и заменить обработку, выполненную для предка. Вам необходимо определить, нужно ли выполнять пользовательское форматирование при обработке самого узла w:p.

Один из способов сделать это - переопределить ваш шаблон для w:p узлов, чтобы у вас было

  • общий шаблон для w:p узлов
  • переопределяющий шаблон для w:p узлов, которые являются ближайшим предком особого случая w:sdt узел

Чтобы определить, является ли w:p ближайшим предком или нет, вы можете использовать xsl:key.

* * Пример тысяча двадцать-один: * * 1 022
<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 элементов.

0 голосов
/ 02 апреля 2010

Подход к обработке родителя после его дочернего элемента неверен для приложения XSLT .

Пожалуйста, предоставьте рабочий (но наименьший возможный) пример, содержащий исходный XML-документ и фактическую таблицу стилей xslt. Также объясните, какие выходные данные должны быть получены и как выходные данные получены из исходного XML-документа.

При этом родитель текущего узла выбирается этим простым выражением XPath :

..
0 голосов
/ 02 апреля 2010

Как насчет parent::* или просто ..?

...