有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何为XSL转换提供参数?

我正在跟踪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) 个答案

  1. # 1 楼答案

    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机制)