2014-05-04 74 views
1

我是XSLT,XSL和XML操作技術的新手。現在我做一些簡單的轉換,以這個例子XML:帶模板設備的XSLT遞歸直通輸出

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="main.xsl"?> 
<content base-url="../../../"> 
    <article title="TITLE_HERE" timestamp="TIME_HERE"> 
     <p>SOME TEXT HERE <a href="URL.xml">LINKTEXT</a>.</p> 
    </article> 
</content> 

運用這一「main.xsl」轉型:

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

<xsl:output method="xml" 
      version="1.0" 
      encoding="UTF-8" 
      doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" 
      doctype-public="-//W3C//DTD XHTML 1.1//EN" 
      indent="yes"/> 

<xsl:strip-space elements="*"/> 

<xsl:param name="base" 
      select="/content/@base-url"/> 

<!-- PAGE TEMPLATE --> 
<xsl:template match="/content"> 
    <html lang="en"> 
     <head> 
      ... 
     </head> 
     <body> 
      <div class="content"> 
       <xsl:apply-templates match="article"/> 
      </div> 
     </body> 
    </html> 
</xsl:template> 

<!-- ARTICLE NODE TEMPLATE --> 
<xsl:template match="article"> 
    <h2> 
     <xsl:value-of select="@title"/> 
    </h2> 
    <h3> 
     <xsl:value-of select="@timestamp"/> 
    </h3> 
    <xsl:copy-of select="."/> 
</xsl:template> 

</xsl:stylesheet> 

正如你所看到的,複製的使用。問題在於錨鏈接。當使用複製的,我不能用concat函數,如使用模板中:

<xsl:template match="a"> 
    <a href="{concat($base, @href)}"> 
     <xsl:value-of select="."/> 
    </a> 
</xsl:template> 

所以,基本上,還需要使用一些遞歸將輸出整個節點(標記和屬性),但沒有孩子的(文本和其他),遞歸解析它們與指定的模板。

這怎麼辦?

+2

搜索「身份轉換」或「身份模板」 - 字面上有其他SO問題數百個這種技術的例子(和其它地方的網頁),還有一個例子[在XSLT規範中](http://www.w3.org/TR/xslt#copying)。 –

+1

引用_「需要使用某些遞歸」_:在XSLT中,通過使用匹配模板和「xsl:copy」來自然遞歸當前節點的淺表副本。 LingaMurthy的答案顯示瞭如何完成,而不必顯式編寫遞歸函數或調用模板。你使用的'xsl:copy-of'會立即複製所有的孩子,而不進一步處理它們,如果你想對這些孩子做些什麼(如你的例子),那麼它就沒用了。 – Abel

回答

2

您可以使用以下XSLT: 與「node()| @ *」匹配的新模板照原樣複製節點和屬性。而不是複製的我用應用模板:

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

<xsl:output method="xml" 
     version="1.0" 
     encoding="UTF-8" 
     doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" 
     doctype-public="-//W3C//DTD XHTML 1.1//EN" 
     indent="yes"/> 

<xsl:strip-space elements="*"/> 

<xsl:param name="base" 
     select="/content/@base-url"/> 

<!-- PAGE TEMPLATE --> 
<xsl:template match="/content"> 
    <html lang="en"> 
     <head> 
     ... 
     </head> 
     <body> 
      <div class="content"> 
       <xsl:apply-templates select="article"/> 
      </div> 
     </body> 
    </html> 
</xsl:template> 

<xsl:template match="a"> 
    <a href="{concat($base, @href)}"> 
     <xsl:value-of select="."/> 
    </a> 
</xsl:template> 

<!-- ARTICLE NODE TEMPLATE --> 
<xsl:template match="article"> 
    <h2> 
     <xsl:value-of select="@title"/> 
    </h2> 
    <h3> 
     <xsl:value-of select="@timestamp"/> 
    </h3> 
    <xsl:apply-templates/> 
</xsl:template> 

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

</xsl:stylesheet> 
+0

非常感謝,真正需要的! – Anthony