2013-02-23 117 views
3

我是XSLT新手,所以我非常感謝任何幫助。 我在stackoverflow上搜索了很多,試圖應用幾種方法,但失敗了。根據其他屬性值替換xml屬性

我有一個這樣的XML:

<?xml version="1.0" encoding="utf-8"?> 
     <asset_detail> 
      <asset id="1" show_type="Movies"> 
      <title><![CDATA[Movie]]></title> 
      <media_list> 
       <media id="11" title="" type="trailer"> 
       <version format="m3u8" rel_path="/Content/movie.m3u8"/> 
       <version format="HLS" rel_path="/movies/movie.m3u8"/> 
       </media> 
       </media_list> 
      </asset> 
     </asset_detail> 

我應該複製整個XML和:

if media_list/media/version/@format = '**HLS**' I need to replace **@rel_path** with 
value: **concat**(existing value of **@rel_path****,** **someVariable** 
(I'm passing to xsl as a <xsl:param>) 

我想我必須使用類似:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="@*|node()"> 
     <xsl:param name="someVariable"/> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="media/version"> 
     <xsl:attribute name="rel_path"> 
      <xsl:choose> 
       <xsl:when test="./@format = HLS"> 
        <xsl:value-of select="concat(rel_path,$someVariable)"> 
       </xsl:when> 
      </xsl:choose> 
     </xsl:attribute> 
    </xsl:template> 
</xsl:stylesheet> 

我知道它不起作用:)

回答

7

較短的解決方案,使用AVT(屬性值模板):

<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:param name="psomeParam" select="'/xxx'"/> 

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

<xsl:template match="version[@format='HLS']"> 
    <version rel_path="{@rel_path}{$psomeParam}"> 
    <xsl:apply-templates select="@*[not(name()='rel_path')] | node()"/> 
    </version> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔被應用於這種轉變:

<asset_detail> 
    <asset id="1" show_type="Movies"> 
     <title><![CDATA[Movie]]></title> 
     <media_list> 
      <media id="11" title="" type="trailer"> 
       <version format="m3u8" rel_path="/Content/movie.m3u8"/> 
       <version format="HLS" rel_path="/movies/movie.m3u8"/> 
      </media> 
     </media_list> 
    </asset> 
</asset_detail> 

有用,正確結果產生:

<asset_detail> 
    <asset id="1" show_type="Movies"> 
     <title>Movie</title> 
     <media_list> 
     <media id="11" title="" type="trailer"> 
      <version format="m3u8" rel_path="/Content/movie.m3u8"/> 
      <version rel_path="/movies/movie.m3u8/xxx" format="HLS"/> 
     </media> 
     </media_list> 
    </asset> 
</asset_detail> 
+0

+1使用AVT更簡潔。 – Cumbayah 2013-02-23 21:29:11

1

Yo你非常接近。傳遞給樣式表的全局參數應該在外層聲明(移動到output元素的後續兄弟節點)。 HLS格式匹配也可以直接在模板[@format='HLS']中完成。您還錯過了value-of上的一個結束元素標記。最後,你不能直接改變匹配元素的屬性;因此copy下面元件中,發光與現有屬性+更新格式的匹配元素:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:param name="someVariable"/> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="media/version[@format='HLS']"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <xsl:attribute name="rel_path"> 
       <xsl:value-of select="concat(@format,$someVariable)"/> 
      </xsl:attribute> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

希望這有助於。