2014-03-19 105 views
1

我有這樣的XML片段如何使用XSLT構建字符串?

<MediaTypes> 
    <DVD>true</DVD> 
    <HDDVD>false</HDDVD> 
    <BluRay>true</BluRay> 
</MediaTypes> 

我想創建一個輸出看起來像這樣

DVD/Blu-ray 

或類似這樣的

DVD 

或類似這樣的

DVD/HD-DVD/Blu-ray 

取決於真/假狀態

但我是XSLT遊戲中的總新手。 : -/

下面是完整的XML

<?xml version="1.0" encoding="Windows-1252"?> 
<Collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <DVD> 
    <ProfileTimestamp>2012-06-07T05:20:51Z</ProfileTimestamp> 
    <ID>0044005507027.5</ID> 
    <MediaTypes> 
     <DVD>true</DVD> 
     <HDDVD>false</HDDVD> 
     <BluRay>false</BluRay> 
    </MediaTypes> 
    <UPC>0-044005-507027</UPC> 
    <CollectionNumber>448</CollectionNumber> 
    <CollectionType IsPartOfOwnedCollection="true">Owned</CollectionType> 
    <Title>The Big Lebowski</Title> 
    <DistTrait /> 
    <OriginalTitle /> 
    <CountryOfOrigin>United States</CountryOfOrigin> 
    ... 
    </DVD> 
    <DVD> 
    ... 
    </DVD> 
</Collection> 

我試圖按照(關於循環)給出的建議的一個片斷,但它似乎並沒有工作。

這是XSL我到目前爲止(完成):

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

    <xsl:template name="MediaTypes" match="MediaTypes"> 
     Test 
     <xsl:for-each select="*[.='true']">    
      <xsl:value-of select="name()"/> 
      <xsl:if test="position()!=last()"> 
       <xsl:text>/</xsl:text> 
      </xsl:if> 
     </xsl:for-each>   
    </xsl:template> 

    <xsl:template match="/"> 
     <html> 
      <head> 
       <title>DVD Profiler Double Dips</title> 
      </head> 
      <body> 
       <div> 
        <h1>DVD Profiler Double Dips</h1> 
       </div> 
       <table border="1" cellpadding="3" cellspacing="0"> 
        <tr> 
         <th>Title</th> 
         <th>Edition</th> 
         <th>Production Year</th> 
         <th>DVD /</th> 
         <th>Purchase Date</th> 
         <th>Collection Type</th> 
         <th>Original Title</th> 
         <th>Sort Title</th> 
        </tr> 
        <xsl:for-each select="/Collection/DVD"> 
         <tr> 
          <td> 
           <xsl:value-of select="Title"/> 
          </td> 
          <td> 
           <xsl:if test="DistTrait != ''"> 
            <xsl:value-of select="DistTrait"/> 
           </xsl:if> 
           <xsl:if test="DistTrait = ''"> 
            &#160; 
           </xsl:if> 
          </td> 
          <td> 
           <xsl:if test="ProductionYear != ''"> 
            <xsl:value-of select="ProductionYear"/> 
           </xsl:if> 
           <xsl:if test="ProductionYear = ''"> 
            &#160; 
           </xsl:if> 
          </td> 
          <td> 
           <xsl:call-template name="MediaTypes" /> 
          </td> 
         </tr> 
        </xsl:for-each> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

但是,在

<xsl:call-template name="MediaTypes" /> 

是站着的,只有 「測試」 出來

耶!

你們真棒。是

<xsl:apply-templates select="MediaTypes"/> 

是我選擇的武器。

我最後的模板看起來是這樣的:

<xsl:template name="MediaTypes" match="MediaTypes"> 
    <xsl:for-each select="*[.='true']"> 
     <xsl:value-of select="name()"/> 
     <xsl:if test="position()!=last()"> 
      <xsl:text>/</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
    <xsl:if test="CustomMediaType != ''"> 
     <xsl:if test="*[.='true']"> 
      <xsl:text>/</xsl:text> 
     </xsl:if> 
     <xsl:value-of select="CustomMediaType"/> 
    </xsl:if> 
</xsl:template> 

開始理解的東西是如何工作的

感謝您的幫助!

+0

XSLT的什麼版本DVD/BluRay

測試?你可以使用2.0還是僅限於1.0,如果使用1.0,那麼你將使用哪種XSLT處理器? –

+0

嚴,所以你想使用元素而不是他們的內容作爲你的輸出?這有點不同尋常 –

+0

@IanRoberts我想將這個XSL放入一個XML文件的頭部,然後讓任何瀏覽器向我展示一個HTML。 –

回答

3

這個問題相當微不足道 - 真正的問題是您只能顯示XML文檔的片段。 XSLT非常依賴於上下文。

這是一個匹配任何<MediaTypes>元素並輸出所需字符串的模板;希望你能知道如何將其納入自己的樣式表:

<xsl:template match="MediaTypes"> 
    <xsl:for-each select="*[.='true']"> 
     <xsl:value-of select="name()"/> 
     <xsl:if test="position()!=last()"> 
      <xsl:text>/</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 
+0

我已經試過了,但它似乎沒有進入for-each循環 我已經進入到我的代碼,這 的 \t Test / 的 和稍後當我需要它,我寫 的 但是唯一的輸出是「Test」:-( –

+1

@ DeeJ.Doena您可能需要使用'apply-templates'而不是'call-template'來確保上下文節點是正確的 - 使用''上下文節點將保留在調用點的任何位置,但是使用'它會正確地將上下文重置到MediaTypes元素。 –

+0

@ DeeJ.Doena我建議你編輯你的問題來包含你的XSLT和你希望得到的輸出(作爲代碼)。 –

0

我建議你更改XML有點

下面是一個例子

<?xml version="1.0" ?> 
<?xml-stylesheet type="text/xsl" ?> 
<MediaTypes> 
    <Media name="DVD">true</Media> 
    <Media name="HDDVD">false</Media> 
    <Media name="BluRay">true</Media> 
</MediaTypes> 

這樣你可能會寫入XPATH表達式,如//MediaTypes/Media 但是@michael。hor257k寫一個很好的解決方案,這頂格局XML成看起來像這樣

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="//MediaTypes"> 
     <xsl:for-each select="*[.='true']"> 
      <xsl:value-of select="@name"/> 
      <xsl:if test="position()!=last()"> 
       <xsl:text>/</xsl:text> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

這將使這裏http://xslttest.appspot.com/

+0

謝謝,但遺憾的是XML不是我的: - / –