2010-08-22 54 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); 
}