2013-04-03 44 views
2

該XML具有要附加的字符串,要添加的字符串長度和字符的詳細信息。將字符附加到XSL中的字符串

<?xml version="1.0" encoding="ISO-8859-1"?> 
<data> 
    <input> 
     <string>Auckland</string> 
     <len>12</len> 
     <char>#</char> 
    </input> 

    <input> 
     <string>Ohio</string> 
     <len>3</len>  
     <char>*</char> 
    </input> 
</data> 

我也有一個XSLT應(理想情況下)使用此邏輯: 而(字符串<指定長度的長度){ 串連(炭,字符串) } 別的 {截斷字符串與指定的長度}

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template name="append" match="/"> 
    <xsl:param name="char"></xsl:param> 
    <xsl:param name="string"></xsl:param> 
    <xsl:param name="len"></xsl:param> 
    <xsl:value-of select="$string" /> 
    <html> 
    <body> 
    <xsl:for-each select="data/input"> 
     <xsl:choose> 
      <xsl:when test="string-length(string) &lt; len" > 
       <xsl:call-template name="append"> 
        <xsl:with-param name="char" select="char" /> 
        <xsl:with-param name="string" select="concat(char,string)" /> 
        <xsl:with-param name="len" select="len" /> 
       </xsl:call-template> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:for-each> 
    </body> 
    </html> 
</xsl:template> 
</xsl:stylesheet> 

由於某些原因,循環未按預期工作。循環執行一次並顯示結果。

例如,對於第一個XML輸入,輸出應該是####奧克蘭,但結果是#Auckland。你能幫我找出這個代碼中的缺陷嗎?預先感謝您的幫助。

+0

你在字段參數('')中傳遞一個值,但期望字符串參數(''),所以你永遠不會使用你的通過。 – Pawel

+0

這是一個錯字。剛糾正它。 o/p正如之前所述#奧克蘭而不是####奧克蘭 – user2241388

+0

您需要使用$ len,而不是len等,但更基本的是,這沒有任何工作機會。每次通過循環,您都會生成另一組'html'和'body'標記。你需要分開處理「/」情況和做字符串填充的邏輯。 – 2013-04-03 17:34:21

回答

0

當我想你的XSLT,我沒有得到任何文本輸出,因爲在你的代碼主要是,你命名追加模板期望參數len個,但你用的參數調用它字段長度。此外,您命名的模板也與頂級文檔元素相匹配,並且按照它的規定,它將多次輸出多個文檔元素。

儘管有一個匹配的模板也是一個命名模板,但它是完全正確的。試試這個XSLT來代替:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <html> 
     <body> 
      <xsl:apply-templates select="data/input"/> 
     </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="input" name="append"> 
     <xsl:param name="char" select="char"/> 
     <xsl:param name="string" select="string"/> 
     <xsl:param name="length" select="number(len)"/> 
     <xsl:choose> 
     <xsl:when test="string-length($string) &lt; $length"> 
      <xsl:call-template name="append"> 
       <xsl:with-param name="char" select="$char"/> 
       <xsl:with-param name="string" select="concat($char,$string)"/> 
       <xsl:with-param name="length" select="$length"/> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <div> 
       <xsl:value-of select="$string"/> 
      </div> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

當適用於您的XML,下面是輸出

<html> 
<body> 
<div>####Auckland</div> 
<div>Ohio</div> 
</body> 
</html> 

注意的參數使用默認值。第一次訪問模板時,通過模板匹配,值將默認爲相關元素的值。當您隨後將其稱爲命名模板時,它將使用您將其作爲參數傳遞給它的值。

編輯:如果你想,如果他們超過所需長度截斷值,只需更換現有<xsl:value-of select="$string"/>這一行:

<xsl:value-of select="substring($string, 1, $length)"/> 
+0

非常感謝你的詳細解釋。 :)現在,我已經理解參數如何被調用以及匹配和命名模板。 – user2241388

+0

我的第二個'div'應該包含'Ohi' - 截斷長度爲3,因爲這是輸入文件中所需的長度。輕鬆修復XSL ... – MiMo

+0

好點!我已經修改了我的答案來證明這一點。謝謝! –

1

我假設你指定使用XSLT 1.0;這將是2.0中的一個簡單單線程。 但是,如果您願意假設字符串的最大長度,我們仍然可以做一些簡單的事情。

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template name="append" match="/"> 
     <html> 
      <body> 
       <xsl:for-each select="data/input"> 
        <xsl:value-of select="substring(concat(char,char,char,char,char,char,char,char,char,char,.), 10 + string-length() - len, len)"/> 
       </xsl:for-each> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

如果你不快樂與最大長度的假設下,你可以隨時使用黑客:

<xsl:variable name="char" select="char"/> 
<xsl:variable name="chars"> 
    <xsl:for-each select="//*[position() &lt;= $len]"> 
     <xsl:value-of select="$char"/> 
    </xsl:for-each> 
</xsl:variable> 

其中除len工作比節點的輸入文檔的數量較大。然後,你可以做

<xsl:for-each select="data/input"> 
    <xsl:value-of select="substring($chars,.), string-length(), len)"/> 
</xsl:for-each> 

底線,雖然遞歸技術常見於XSLT 1.0,是學習有用的,它是不是在這種特殊情況下確有必要。

2

下面是一個簡單的,高效的和非遞歸XSLT 1.0溶液

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:param name="pFiller" select= 
"'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$'"/> 


    <xsl:template match="/"> 
     <html> 
     <body> 
      <xsl:apply-templates select="data/input"/> 
     </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="input"> 
    <div> 
    <xsl:value-of select= 
    "concat(string, substring(translate($pFiller,'$', char), 1, len))"/> 
    </div> 
    </xsl:template> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔應用:

<data> 
    <input> 
     <string>Auckland</string> 
     <len>12</len> 
     <char>#</char> 
    </input> 
    <input> 
     <string>Ohio</string> 
     <len>3</len> 
     <char>*</char> 
    </input> 
</data> 

的通緝,會產生正確的結果:

<html> 
    <body> 
     <div>Auckland############</div> 
     <div>Ohio***</div> 
    </body> 
</html>