如何为XSL转换提供参数?

时间:2014-01-04 12:18:36

标签: java xml xslt

我正在关注this article以获取iTunes播放列表的内容 作者说,以下XSL可用于将命名的iTunes播放列表转换为M3U格式:

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

  <xsl:output method="text" />

  <xsl:param name="playlist" />

  <xsl:variable name="newline">
<xsl:text>
</xsl:text>
  </xsl:variable>

  <xsl:template match="/">
    <xsl:for-each select="plist/dict/key[text()='Playlists']/
following-sibling::array/dict/key[text()='Name']/
following-sibling::string[text()=$playlist]/
following-sibling::key[text()='Playlist Items']/
following-sibling::array/dict">
      <xsl:call-template name="track">
        <xsl:with-param name="trackid" select=
"key[text()='Track ID']/following-sibling::integer" />
      </xsl:call-template>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="track">
    <xsl:param name="trackid" />
      <xsl:variable name="url" 
select="//plist/dict/key[text()='Tracks']/
following-sibling::dict/dict/key[text()='Track ID']/
following-sibling::integer[text()=$trackid]/../
key[text()='Location']/following-sibling::string" />
<xsl:value-of select="$url" /><xsl:value-of select="$newline" />
    </xsl:template>

</xsl:stylesheet>

我该怎么做?从我到目前为止学到的关于XSL的知识,我想我可能不得不用播放列表的名称替换 $ playlist 。我对吗?如果是,我怎么能有效地做到这一点,作为以下代码的补充:

public String getPlaylist(String playlist) {
    Source source = new StreamSource(library);
    StreamSource xsl = new StreamSource(getClass().getResourceAsStream("M3Utransformation.xml"));
    StringWriter w = new StringWriter();
    Result result = new StreamResult(w);
    try {
        Transformer transformer = TransformerFactory.newInstance().newTransformer(xsl);
        transformer.transform(source, result);
        return w.getBuffer().toString();
    } catch (Throwable t) {
        t.printStackTrace();
        return null;
    }
}

1 个答案:

答案 0 :(得分:0)

Transformer有一个API来传递参数值,您只需要添加

transformer.setParameter("playlist", playlist);

transformer.transform(...)行之前。

如果您要反复调用此方法,那么每次加载和编译样式表时,只需加载一次,然后重新使用相同的Transformer以便将来调用:

private Transformer transformer = null;

public String getPlaylist(String playlist) {
    if(transformer == null) {
        StreamSource xsl = new StreamSource(getClass().getResourceAsStream("M3Utransformation.xml"));
        try {
            transformer = TransformerFactory.newInstance().newTransformer(xsl);
        } catch (Throwable t) {
            t.printStackTrace();
            return null;
        }
    }
    StringWriter w = new StringWriter();
    Source source = new StreamSource(library);
    Result result = new StreamResult(w);
    try {
        transformer.setParameter("playlist", playlist);
        transformer.transform(source, result);
        return w.getBuffer().toString();
    } catch (Throwable t) {
        t.printStackTrace();
        return null;
    }
}

(请注意,Transformer不是线程安全的,因此,如果您要从多个线程拨打电话,则需要使用Templates机制

相关问题