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

发布于 2024-09-30 17:48:58 字数 3199 浏览 1 评论 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() 数字。我只需要通过变量来完成此操作,如果您可以在变量 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">

Input

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

Output should be

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

Stylesheet

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

Problem: I need to print all the heading text values under "name" element. But if there is similar text value present for previous hading it should add position() number before the text values. I need to do it though variable only, if you can see in Variable name1 i am trying to put some logic which will compare the value of previous heading and if come across the similar text then put the position number, but somehow am not able to achieve that. Can you please help me write same logic in variable name1. Thanks in advance for your help.

______Edited_________

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏夜暖风 2024-10-07 17:48:58

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

万一您需要结果中生成的每个文本节点实际上位于变量中,然后只需将上述代码中的 替换为 ;

One of the simplest possible XSLT 2.0 solutions:

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

when applied on the provided XML document:

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

produces the wanted, correct result:

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

In case you need each of the text nodes produced in the result to be actually in variables, then simply replace in the above code <xsl:sequence> with <xsl:variable>.

心清如水 2024-10-07 17:48:58

这是一个示例样式表,可生成您要求的结果:

<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', .)[. << 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>

Here is a sample stylesheet that produces the result you asked for:

<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', .)[. << 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文