2010-08-22 102 views
3

我使用VS 2008,.net 3.5使用XSLT生成頁面html。替換 r n使用XSLT和.NET的換行符VS 2008

我有信息,包含\ r \ n(新行)

我在XSL文件中使用此:

<b>Message: </b><xsl:value-of select="Message"/><br/> 

我需要<br/>在XSL替換\ r \ n。我見過幾個引用,但對我的問題沒有得到解決:

我使用此代碼C#之前,我打電話變換XSLT,但不正確的:

m = m.Replace(@"\r\n", "&#xD;&#xA;"); 
      m = m.Replace(@"\n", "&#xA;"); 
      //m = System.Web.HttpUtility.HtmlDecode(m); 

      m = m.Replace(@"\r\n", "<br/>"); 
      m = m.Replace(@"\n", "<br/>"); 
      msg = "<Exception>" 
      + "<Description>" + d + "</Description>" 
      + "<Message>" + m + "</Message>" 
      + "<DateTime>" + localTimeString + "</DateTime>" 
      + "</Exception>"; 

我用這個引用,而不是解決方案

Interpreting newlines with xsl:text?

XSLT Replace function not found

的替換功能只在XSLT 2.0版可用,而不是在版本sion 1.0是Visual Studio使用的。僅僅因爲你指定了version =「2.0」並不意味着Visual Studio支持它。

我用這個像的最後一個引用,但我得到的錯誤:

<xsl:call-template name="string-replace-all"> 
     <xsl:with-param name="text" select="Message"/> 
     <xsl:with-param name="replace" select="\r\n"/> 
     <xsl:with-param name="by" select="&lt;br/&gt;"/> 
</xsl:call-template> 

建議,任何示例代碼工作?

+0

好問題(+1)。查看我的答案以解釋問題和完整的解決方案。 :) – 2010-08-22 15:13:41

回答

8

上面的調用模板看起來不錯,您只需要模板就可以了!

<!-- XSL FILE --> 


<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
     version="1.0"> 
    <xsl:variable name="_crlf"><xsl:text> 
</xsl:text></xsl:variable> 
    <xsl:variable name="crlf" select="string($_crlf)"/> 
    <xsl:template match="/"> 

    <xsl:for-each select="//demo"> 
     Demo: 
     <xsl:call-template name="crlf-replace"> 
    <xsl:with-param name="subject" select="./text()"/> 
     </xsl:call-template> 
    </xsl:for-each> 
    </xsl:template> 

    <xsl:template name="crlf-replace"> 
    <xsl:param name="subject"/> 

    <xsl:choose> 
     <xsl:when test="contains($subject, $crlf)"> 
    <xsl:value-of select="substring-before($subject, $crlf)"/><br/> 
    <xsl:call-template name="crlf-replace"> 
     <xsl:with-param name="subject" select="substring-after($subject, $crlf)"/> 
    </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
    <xsl:value-of select="$subject"/> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 


<!-- XML FILE --> 

<?xml version="1.0"?> 

<demos> 
    <demo>xslt is really fun</demo> 
    <demo>you quite often use recursion in xslt</demo> 
    <demo>so there!</demo> 
</demos> 
+0

我有模板,但獲取錯誤,使用字符串搜索參數:「\ r \ n」 – Kiquenet 2010-08-22 12:40:49

+1

注意從樣式表文本中定義CRLF的入侵 - 不要縮進此文本,否則方法會中斷!另外 - 我在Linux上,所以如果你從這個答案中剪切粘貼,你可能得不到完整的CRLF – Robin 2010-08-22 12:47:36

+0

這種定義「新行」的方式並不好,因爲這種縮進限制。聲明這樣的變量的有效方法是:'' – 2010-08-23 13:52:55

5

有兩個問題在這裏

  1. 你不應該試圖取代CRLF - 這樣的字符串中不存在的文本。原因在於任何兼容的XML解析器都通過用一個LF替換任何CR + LF組合來規範化文本節點(&#xA)。 W3C XML Specification說: 「爲簡化應用程序的任務,無論外部解析實體或內部解析實體的文字實體值包含文字雙字符序列」#xD#xA「還是獨立文字# XD,XML處理器必須傳遞給應用程序的單個字符#xA。(此行爲可方便地通過歸一化所有換行符來#xA上輸入,解析之前進行製造。)

  2. 替換當不可t是一個字符串。它應該是一個節點 - <br />

修復這兩個問題很簡單:

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

<xsl:template match="text()" name="replaceNL"> 
    <xsl:param name="pText" select="."/> 

    <xsl:choose> 
    <xsl:when test="contains($pText, '&#xA;')"> 
     <xsl:value-of select= 
     "substring-before($pText, '&#xA;')"/> 
     <br /> 
     <xsl:call-template name="replaceNL"> 
     <xsl:with-param name="pText" select= 
      "substring-after($pText, '&#xA;')"/> 
     </xsl:call-template> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:value-of select="$pText"/> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
</xsl:stylesheet> 

當這一轉型是這個XML文檔施加:

<Exception> 
<Description>Quite common error: 
Missing '(' 
</Description> 
<Message>Error1001: 
Syntax error 2002 
</Message> 
<DateTime>localTimeString</DateTime> 
</Exception> 

想要的,正確的結果產生

<Exception> 
    <Description>Quite common error:<br/> Missing '('<br/> </Description> 
    <Message>Error1001:<br/> Syntax error 2002<br/> </Message> 
    <DateTime>localTimeString</DateTime> 
</Exception> 
+0

Dimitre是,所述解析的文本不正確包含字符串CRLF,即使文檔具有Windows換行符。但是,如果AFAIK特別使用字符實體寫入文檔,則該文檔可以包含CRLF組合。如果您只是使用'&#xD&#xA'而不是'&#xA',那麼Dimitre的答案也適用於這種罕見的情況。 – jasso 2010-08-22 22:26:00

0

我不得不將數據庫數據寫入一個xml文件,並使用LINQ to XML從xml文件中讀取它。記錄中的某些字段本身是xml字符串,包含\ r字符。這些必須保持完好。我花了好幾天的時間試圖找到可行的東西,但似乎微軟正在設計將\ r轉換成\ n。

以下解決方案爲我工作:

要編寫一個加載的XDocument到XML文件保存\ r完好,其中XDOC是一個XDocument和文件路徑是一個字符串:

XmlWriterSettings xmlWriterSettings = new XmlWriterSettings 
    { NewLineHandling = NewLineHandling.None, Indent = true }; 
using (XmlWriter xmlWriter = XmlWriter.Create(filePath, xmlWriterSettings)) 
{ 
    xDoc.Save(xmlWriter); 
    xmlWriter.Flush(); 
} 

要閱讀XML文件轉換爲XElement \ r完好無損:

using (XmlTextReader xmlTextReader = new XmlTextReader(filePath) 
    { WhitespaceHandling = WhitespaceHandling.Significant }) 
{ 
    xmlTextReader.MoveToContent(); 
    xDatabaseElement = XElement.Load(xmlTextReader); 
}