在以前节点的变量中存储文本值

时间:2010-11-04 10:19:56

标签: xslt-2.0 xpath-2.0

输入

<?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>

样式表

<?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”元素下打印所有标题文本值。但是,如果先前的hading存在类似的文本值,则应在文本值之前添加position()数字。我只需要变量就可以做到这一点,如果你可以在变量名1中看到我试图放一些逻辑来比较前一个标题的值,如果遇到类似的文本然后放位置号,但不知何故我不能实现这一点。你能帮我在变量名1中写同样的逻辑吗?在此先感谢您的帮助。

__ _ ___ 被修改 _ < / EM> __ _ __ _ __

<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 :(得分:0)

以下是一个示例样式表,用于生成您要求的结果:

<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>

答案 1 :(得分:0)

最简单的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>