XML和变量

时间:2012-05-14 06:20:59

标签: xml xslt

我正在研究一个项目并遇到问题。 我最近确定一个人不能改变变量值,似乎无法找到解决这个问题的方法。我需要创建通用的代码,我无法做到这一点。

我的XSLT代码 .........

                   <tracklist>
                        <xsl:for-each select = "VinylRecord/Tracks/Song">

                            <xsl:choose>

                                <xsl:when test = "@Track = 1">
                                    <xsl:element name="side{@Side}">

                                    <xsl:variable name = "d" select = "@Track"/>

                                        <xsl:for-each select = "../Song">
                                            <xsl:choose>
                                                <xsl:when test = "@Side = ../Song/following:: @Side">

                                                    <track>

                                                        <xsl:attribute name = "no">
                                                            <xsl:value-of select = "@Track" />
                                                        </xsl:attribute>

                                                        <xsl:attribute name = "runtime">
                                                            <xsl:value-of select = "Length" />
                                                        </xsl:attribute>

                                                        <xsl:value-of select = "text()" />

                                                    </track>

                                                </xsl:when>                                               
                                            </xsl:choose>
                                        </xsl:for-each>


                                    </xsl:element>
                                </xsl:when>

                            </xsl:choose>

                        </xsl:for-each>
                    </tracklist>

XML文档 ............

    <Tracks>
        <Song Side="A" Track="1">
            The Nerve
            <Length>2.58</Length>
        </Song>
        <Song Side="A" Track="2">
            Backfire
            <Length>3.22</Length>
        </Song> 
        <Song Side="A" Track="3">
            Clipping
            <Length>4.05</Length>
        </Song>
        <Song Side="A" Track="4">
            Spotlight
            <Length>3.21</Length>
        </Song>
        <Song Side="A" Track="5">
            No Response
            <Length>4.01</Length>
        </Song>
        <Song Side="A" Track="6">
            Pins and Needles
            <Length>4.05</Length>
        </Song>
        <Song Side="B" Track="1">
            Goodbye
            <Length>4.09</Length>
        </Song>
        <Song Side="B" Track="2">
            Odds
            <Length>3.01</Length>
        </Song>
        <Song Side="B" Track="3">
            Electrify
            <Length>3.49</Length>
        </Song>
        <Song Side="B" Track="4">
            Armistice
            <Length>3.54</Length>
        </Song>
        <Song Side="B" Track="5">
            Lost Year
            <Length>3.13</Length>
        </Song>
        <Song Side="B" Track="6">
            Burden
            <Length>9.06</Length>
        </Song>
    </Tracks>

...

任何提示都将非常感谢

预期结果 ...............

这只是上面显示的整个程序的片段,但结果假设显示为:

        <tracklist>
            <sideA>
                <track no="1" runtime="2.58">The Nerve</track>
                <track no="2" runtime="3.22">Backfire</track>
                <track no="3" runtime="4.05">Clipping</track>
                <track no="4" runtime="3.21">Spotlight</track>
                <track no="5" runtime="4.01">No Response</track>
                <track no="6" runtime="4.05">Pins and Needles</track>
            </sideA>
            <sideB>
                <track no="1" runtime="4.09">Goodbye</track>
                <track no="2" runtime="3.01">Odds</track>
                <track no="3" runtime="3.49">Electrify</track>
                <track no="4" runtime="3.54">Armistice</track>
                <track no="5" runtime="3.13">Lost Year</track>
                <track no="6" runtime="9.06">Burden</track>
            </sideB>
        </tracklist>

3 个答案:

答案 0 :(得分:0)

“这不是一个错误,它是一个功能”:XSLT变量的设计是不可更改的。实际上它们可以被命名为常量。解决这个问题很困难,可以使用参数来完成。在大多数情况下,如果使用XSLT编程尝试,则不需要,其中程序由数据通过模板驱动。像“for-each”这样的事情是程序性的方式,并不真正适合XSLT的想法。你想得到什么结果呢?

在知道预期结果后,sylesheet应如下所示:

<xsl:template match="Tracks">
 <tracklist>
  <sideA>
   <xsl:apply-templates select="Song[@Side='A']"/>
  </sideA>
  <sideB>
   <xsl:apply-templates select="Song[@Side='B']"/>
  </sideB>
 </tracklist>
</xsl:template>
<xsl:template match="Song">
 <track no="{@Track}" runtime="{Length}">
  <xsl:value-of select="text()"/>
 </track>
</xsl:template>

答案 1 :(得分:0)

它看起来像是一个标准的分组问题。

如果您使用的是XSLT 2.0,那么

<xsl:for-each-group select="Song" group-by="Side">
  <xsl:element name="Side{current-grouping-key)}">
    <xsl:for-each select="current-group()">
      <track no="{position()}" runtime="{Length}">
         <xsl:value-of select="."/>
      </track>
    </xsl:for-each>
  </xsl:element>
</xsl:for-each-group>

使用XSLT 1.0它会更加困难,但仍然是教科书问题:查找“Muenchian Grouping”的答案。

答案 2 :(得分:0)

此XSLT解决方案非常简单

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kFollowing" match="Song"
  use="generate-id(preceding-sibling::Song[not(@Side = current()/@Side)][1])"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/*">
  <tracklist>
   <xsl:apply-templates/>
  </tracklist>
 </xsl:template>

 <xsl:template match="Song"/>

 <xsl:template match=
  "Song[not(@Side = preceding-sibling::Song[1]/@Side)]">

  <xsl:element name="side{@Side}">
   <xsl:apply-templates mode="inGroup" select=
   "key('kFollowing', generate-id(preceding-sibling::Song[1]/@side))"/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="Song" mode="inGroup">
  <track no="{@Track}" runtime="{Length}"><xsl:value-of select="text()"/></track>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

应用于提供的XML文档

<Tracks>
    <Song Side="A" Track="1">
            The Nerve
        <Length>2.58</Length>
    </Song>
    <Song Side="A" Track="2">
            Backfire
        <Length>3.22</Length>
    </Song>
    <Song Side="A" Track="3">
            Clipping
        <Length>4.05</Length>
    </Song>
    <Song Side="A" Track="4">
            Spotlight
        <Length>3.21</Length>
    </Song>
    <Song Side="A" Track="5">
            No Response
        <Length>4.01</Length>
    </Song>
    <Song Side="A" Track="6">
            Pins and Needles
        <Length>4.05</Length>
    </Song>
    <Song Side="B" Track="1">
            Goodbye
        <Length>4.09</Length>
    </Song>
    <Song Side="B" Track="2">
            Odds
        <Length>3.01</Length>
    </Song>
    <Song Side="B" Track="3">
            Electrify
        <Length>3.49</Length>
    </Song>
    <Song Side="B" Track="4">
            Armistice
        <Length>3.54</Length>
    </Song>
    <Song Side="B" Track="5">
            Lost Year
        <Length>3.13</Length>
    </Song>
    <Song Side="B" Track="6">
            Burden
        <Length>9.06</Length>
    </Song>
</Tracks>

产生了想要的正确结果:

<tracklist>
   <sideA>
      <track no="1" runtime="2.58">
            The Nerve
        </track>
      <track no="2" runtime="3.22">
            Backfire
        </track>
      <track no="3" runtime="4.05">
            Clipping
        </track>
      <track no="4" runtime="3.21">
            Spotlight
        </track>
      <track no="5" runtime="4.01">
            No Response
        </track>
      <track no="6" runtime="4.05">
            Pins and Needles
        </track>
   </sideA>
   <sideB>
      <track no="1" runtime="2.58">
            The Nerve
        </track>
      <track no="2" runtime="3.22">
            Backfire
        </track>
      <track no="3" runtime="4.05">
            Clipping
        </track>
      <track no="4" runtime="3.21">
            Spotlight
        </track>
      <track no="5" runtime="4.01">
            No Response
        </track>
      <track no="6" runtime="4.05">
            Pins and Needles
        </track>
   </sideB>
</tracklist>