2011-11-23 218 views
0

我有XSLT 1.0標準。 我有一個來自服務器的動態XML非常簡單,第二個XML作爲配置。基於第一個(這是動態的)我必須從第二個挑選合適的節點信息。 這是第一文件:帶動態路徑的XSLT文檔

<?xml version="1.0" encoding="UTF-8" ?> 
<response> 
    <response>SUCCESS</response> 
    <responsedata> 
     <hit> 
      <url>http://domain.com/page.html</url> 
      <id>2437</id> 
      <title>Page title</title> 
      <language>en</language> 
      ... 
      ... 
     </hit> 
    </responsedata> 
</response> 

第二配置XML爲頁腳,報頭由語言分。類似的東西:

<?xml version="1.0" encoding="UTF-8"?> 
<config> 
    <set id="local"> 
     <header> 
      <en> 
       <![CDATA[ 
<div id="header"> 
    <p>English code</p> 
</div> 
       ]]> 
      </en> 
      <fr> 
       <![CDATA[ 
<div id="header"> 
    <p>French code</p> 
</div> 
       ]]> 
      </fr> 
     </header> 
    </set> 
</config> 

我需要拿起正確的語言依賴代碼從第二個XML。 我嘗試下面的代碼,它不工作:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" omit-xml-declaration="yes" encoding="utf-8" indent="yes" doctype-system="about:legacy-compat" /> 
    <xsl:variable name="configuration" select="document('settings.xml')/config/set[@id='local']" /> 
    <xsl:variable name="lang" select="response/responsedata/hit/language" /> 

    <xsl:template name="getvalueofnode"> 
     <xsl:param name="path" /> 
     <xsl:param name="context" select="$configuration" /> 
     <xsl:choose> 
      <xsl:when test="contains($path,'/')"> 
       <xsl:call-template name="getvalueofnode"> 
        <xsl:with-param name="path"  
         select="substring-after($path,'/')" /> 
        <xsl:with-param name="context" 
         select="$context/*[name()=substring-before($path,'/')]" /> 
       </xsl:call-template> 
      </xsl:when> 
      <xsl:otherwise> 
       <p>value: <xsl:value-of select="$context/*[name()=$path]" disable-output-escaping="yes" /></p> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

    <xsl:template match="/"> 
     <xsl:element name="html"> 
      <xsl:attribute name="lang"><xsl:value-of select="$lang" /></xsl:attribute> 
      <xsl:element name="head"> 
       <xsl:attribute name="lang"><xsl:value-of select="$lang" /></xsl:attribute> 
      </xsl:element> 
      <xsl:element name="body"> 
       <xsl:attribute name="lang"><xsl:value-of select="$lang" /></xsl:attribute> 
       <p>lang: <xsl:value-of select="$lang" /></p> 
       <p> 
       <xsl:call-template name="getvalueofnode"> 
        <xsl:with-param name="path" select="concat('/header/',$lang)" /> 
       </xsl:call-template> 
       </p> 
      </xsl:element> 
     </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

如果有人有任何建議或解決方案將是非常美妙的。

回答

1

由於您已經知道基於$lang的元素名稱,因此可以一起消除getvalueofnode模板。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="html" omit-xml-declaration="yes" encoding="utf-8" indent="yes" doctype-system="about:legacy-compat" /> 
    <xsl:variable name="configuration" select="document('settings.xml')/config/set[@id='local']" /> 
    <xsl:variable name="lang" select="response/responsedata/hit/language" /> 

    <xsl:template match="/"> 
    <html lang="{$lang}"> 
     <head lang="{$lang}"/> 
     <body lang="{$lang}"> 
     <p>lang: <xsl:value-of select="$lang" /></p> 
     <p>value: <xsl:value-of disable-output-escaping="yes" select="$configuration/header/*[name()=$lang]"/></p> 
     </body> 
    </html> 
    </xsl:template> 

</xsl:stylesheet> 

我也擺脫了所有的xsl:elementxsl:attribute的。通常可以通過直接對元素進行編碼並使用AVT (attribute value templates)來避免這些屬性。

樣式表產生上述使用XML輸入文件下面的輸出(與撒克遜6.5.5和撒克遜-HE 9.3.0.5測試):

<!DOCTYPE html 
    SYSTEM "about:legacy-compat"> 
<html lang="en"> 
    <head lang="en"> 
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
    </head> 
    <body lang="en"> 
     <p>lang: en</p> 
     <p>value: 

     <div id="header"> 
     <p>English code</p> 
     </div> 


     </p> 
    </body> 
</html> 
+0

它也正常工作。我認爲有更通用的方式來提取信息和操縱數據。 – AlB

+0

爲什麼選擇投票?有一些錯誤信息嗎? –

+0

對不起,如果我確實下降了,那可能是偶然的。我無法改變它。我沒有這個特權。抱歉。 – AlB

0

我不太確定我是否正確地解決了您的問題,但我會盡力嘗試。

當您嘗試使用getvalueofnode模板獲取您的值時,您將提供/header/en作爲路徑。該模板將在第一個斜槓之前切斷字符串,並在您的配置中查找具有該名稱的元素。恰巧,切斷的值是空字符串,它會導致您的模板在配置中查找配置中沒有名稱(不存在)的元素。

$content因此在第二次調用(第一次遞歸調用)中將是空的結果樹片段。因爲它不包含斜線,所以模板會打印不存在的值,因此也會打印空的結果樹片段。由於印刷時,空的樹片段轉換爲空字符串你的輸出將只是:

<p>value: </p> 

關於一個解決方案:只需撥打您首次模板時刪除斜線。這是用途:

<xsl:call-template name="getvalueofnode"> 
    <xsl:with-param name="path" select="concat('header/',$lang)" /> 
</xsl:call-template> 

您的轉換將導致英文標題。

順便說一句,您致電getvalueofnode封裝在<p>,所以它返回它的價值的地方。這導致最終輸出中的嵌套段落標籤。

+0

謝謝。你是絕對正確的。這是導致斜線的一個問題。 – AlB