Хранение текстовых значений в переменной предыдущих узлов - PullRequest
1 голос
/ 04 ноября 2010

Введите

<?xml version="1.0" encoding="UTF-8"?>
<XML>
    <Concept>
        <Heading-1>This is First Heading</Heading-1>
    </Concept>
    <Concept>
        <Heading-2>This is Second Heading</Heading-2>
    </Concept>
    <Concept>
        <Heading-2>This is First Heading</Heading-2>
    </Concept>
 </XML>

Вывод должен быть

<?xml version="1.0" encoding="UTF-8"?>
<name>This_is_First_Heading</name>
<name>This_is_Second_Heading</name>
<name>1_This_is_First_Heading</name>

1007 * стилевой *

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" version="2.0">
    <xsl:template match="Concept">
        <xsl:variable name="name" 
                      select="./Heading-1/text() | ./Heading-2/text()"/>
        <xsl:variable name="name1" 
                      select="if //Cocept/Heading-1/text()=$name 
                              then concat(position(), '_' $name)} 
                              else $name"/>
        <name>
            <xsl:value-of select="replace($name, ' ', '_' )"/>
        </name>
    </xsl:template>
</xsl:stylesheet>

Проблема: мне нужно напечатать все значения текста заголовка в элементе name. Но если есть аналогичное текстовое значение, присутствующее для предыдущего хединга, то оно должно добавить число position () перед текстовыми значениями. Мне нужно сделать это только через переменную, если вы видите в переменной name1, я пытаюсь поместить некоторую логику, которая будет сравнивать значение предыдущего заголовка, и, если встретится с подобным текстом, тогда введите номер позиции, но каким-то образом не могу достичь этого. Можете ли вы помочь мне написать ту же логику в переменной name1. Заранее спасибо за помощь.

__ _ ___ Отредактировано _ __ _ __ _ __

<xsl:template match="Concept">
    <xsl:variable name="name"
                  select="if (./Heading-1[1] |
                              ./Heading-2[1] |
                              ./Heading-3[1] |
                              ./Heading-4[1] |
                              ./Heading-5[1])
                          then normalize-space((Heading-1[1] |
                                                Heading-2[1] |
                                                Heading-3[1] |
                                                Heading-4[1] |
                                                Heading-5[1])
                                                /text()[position()=last()])
                          else normalize-space(./Heading-2[1]/text()[2])"/>
        <xsl:variable name="name1"
                      select="if (//Concept/Heading-3/text()
                                   [position()=last()] = $name)
                              then concat(position(), '_', $name)
                              else $name"></xsl:variable>
        <xsl:variable name="name2"
                      select="if (string-length($name5)=0)
                              then concat(position(), '_', $name5)
                              else $name5"/>
        <xsl:result-document href="XML/{replace($name2, ' ', '_')}.xml"
                             format="testing" validation="strip">

Ответы [ 2 ]

0 голосов
/ 06 ноября 2010

Одно из самых простых решений XSLT 2.0 :

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:template match="/*/*/*">
  <name>
    <xsl:sequence select=
     "concat(for $cnt in count(../preceding-sibling::*/*[. eq current()])
              return 
                if($cnt gt 0)
                  then concat($cnt, '_')
                  else (),
              .
             )
     "/>
  </name>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<XML>
    <Concept>
        <Heading-1>This is First Heading</Heading-1>
    </Concept>
    <Concept>
        <Heading-2>This is Second Heading</Heading-2>
    </Concept>
    <Concept>
        <Heading-2>This is First Heading</Heading-2>
    </Concept>
 </XML>

дает желаемый, правильный результат :

<name>This is First Heading</name>
<name>This is Second Heading</name>
<name>1_This is First Heading</name>

Если вам нужно, чтобы каждый из созданных в результате текстовых узлов был фактически в переменных , просто замените в приведенном выше коде <xsl:sequence> на <xsl:variable>.

0 голосов
/ 04 ноября 2010

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

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="k1" match="Concept/*" use="."/>

  <xsl:template match="Concept/*">
    <xsl:variable name="preceding" select="key('k1', .)[. &lt;&lt; current()]"/>
    <name>
      <xsl:choose>
        <xsl:when test="$preceding">
          <xsl:value-of select="concat(count($preceding), '_', replace(., ' ', '_'))"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="replace(., ' ', '_')"/>
        </xsl:otherwise>
      </xsl:choose>
    </name>
  </xsl:template>

</xsl:stylesheet>
...