1

我有 XML 中的数据,其中包含一些标题信息,然后是一系列项目。我正在使用 XSLT 将其转换为不同的格式,还带有标题区域和一系列项目。

但是,在翻译后的结果中,我希望仅在标题中找到的一条数据包含在项目的每个实例中,即使它只是重复相同的值。(这个值可能会改变,所以我不能硬编码)

样本数据(显着简化)

<rss>
  <channel>
    <title>Playlist One</title>
    <items>
      <item>
        <title>Video One</title>
      </item>
      <item>
        <title>Video Two</title>
      </item>
      <item>
        <title>Video Three</title>
      </item>
    </items>
  </channel>
</rss>

我想要的结果是这样的:

    playlist_header_title=Playlist One

    playlist_title=Playlist One
    video_title=Video One

    playlist_title=Playlist One
    video_title=Video Two

    playlist_title=Playlist One
    video_title=Video Three

我的 XSLT 非常复杂(不幸的是我从其他人那里继承了它,所以我不确定一切都是做什么的,我已经在网上自学了,但有点不知所措)

大致关键部分如下所示:

    <xsl:template name="rss" match="/">
      <xsl:variable name="playlist_title">
        <xsl:value-of select="string(/rss/channel/title)"/>
      </xsl:variable>
      <xsl:for-each select="rss">   
        <xsl:apply-templates name="item" select="channel/items/item"/>
      </xsl:for-each>   
    </xsl:template>

然后是一个名为“item”的巨大模板,我不会在这里包含,但基本上它会根据需要输出所有项目数据,我只是不知道如何访问“playlist_title”。

当我尝试调用时(从模板“项目”内部)

    <xsl:value-of select="string($playlist_title)"/>

它返回一个空白。我认为这是因为该变量是在 for-each 循环之外创建的,因此它不可用。(当我在结果版本的标头中的 for-each 循环之前输出数据时,它会正确显示数据,但这还不够)

我尝试在应用模板中使用 with-param,还尝试在另一个循环中使用 with-param 将其更改为 call-template,但它们也显示为空白。

我还尝试发送字符串而不是从 XML 中提取 playlist_title 只是为了确认我能够将任何值传递到模板中,但它们也出现空白。

例如:

<xsl:for-each select="channel/items/item">  
    <xsl:call-template name="item">
        <xsl:with-param name="playlist_title">blah</xsl:with-param>
    </xsl:call-template>
</xsl:for-each> 


<xsl:template name="item">  
    <xsl:param name="playlist_title" />
            playlist_title=<xsl:value-of select="string($playlist_title)"/>
            video_title=...
    ...
    </xsl:template>

这没有返回值“blah”,而只是一个空白。(我希望然后用从 XML 中提取的 playlist_title 值替换“blah”,但没有一个通过)

我难住了!谢谢你的帮助。

4

1 回答 1

0

在您的第一个示例中,尝试引用$playlist_title模板内部item失败,因为该模板内部不存在该变量。它是在模板匹配中创建的,rss并且是本地范围的。

如果您希望能够$playlist_title在其他模板中使用,则需要rss在“全局范围”中的模板之外声明它。

例如:

<xsl:variable name="playlist_title">
    <xsl:value-of select="string(/rss/channel/title)"/>
</xsl:variable>
<xsl:template name="rss" match="/">
    <xsl:for-each select="rss">   
        <xsl:apply-templates name="item" select="channel/items/item"/>
    </xsl:for-each>   
</xsl:template>

至于您的第二次尝试,引用xsl:param playlist_title,它对我有用。仔细检查以确保在声明的参数名称和您引用的参数名称之间没有类型-o 或其他差异。


您可以尝试这样的事情来实现您想要的输出,使用xsl:variable

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" indent="yes"/>

    <xsl:variable name="playlist_title" select="/rss/channel/title" />

    <xsl:template match="/">
        <xsl:apply-templates select="rss/channel"/>         
    </xsl:template>

    <xsl:template match="channel">
        <xsl:text>playlist_header_title=</xsl:text>
        <xsl:value-of select="title"/>
        <xsl:text>&#xA;&#xA;</xsl:text>
        <xsl:apply-templates select="items/item"/> 
    </xsl:template>

    <xsl:template match="item">  
        <xsl:text>playlist_title=</xsl:text>
        <xsl:value-of select="$playlist_title"/>
        <xsl:text>&#xA;</xsl:text>
        <xsl:text>video_title=</xsl:text>
        <xsl:value-of select="title"/>
        <xsl:text>&#xA;&#xA;</xsl:text>
    </xsl:template>

</xsl:stylesheet>

或者您可以消除xsl:variable并使用xsl:param

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" indent="yes"/>

    <xsl:template match="/">
        <xsl:apply-templates select="rss/channel"/>         
    </xsl:template>

    <xsl:template match="channel">
        <xsl:text>playlist_header_title=</xsl:text>
        <xsl:value-of select="title"/>
        <xsl:text>&#xA;&#xA;</xsl:text>
        <xsl:apply-templates select="items/item">
            <xsl:with-param name="playlist_title" select="title"/>
        </xsl:apply-templates> 
    </xsl:template>

    <xsl:template match="item">
        <xsl:param name="playlist_title" />
        <xsl:text>playlist_title=</xsl:text>
        <xsl:value-of select="$playlist_title"/>
        <xsl:text>&#xA;</xsl:text>
        <xsl:text>video_title=</xsl:text>
        <xsl:value-of select="title"/>
        <xsl:text>&#xA;&#xA;</xsl:text>
    </xsl:template>

</xsl:stylesheet>
于 2013-06-08T19:00:21.547 回答