I use VS 2008, .net 3.5 for generate page html using XSLT.
I have Message, that contains \r\n (newlines)
I use this in XSL file:
<b>Message: </b><xsl:value-of select="Message"/><br/>
I need replace \r\n by <br/>
in xsl. I have seen several references but not get solution for my issue:
I use this code C# before I call to transform XSLT, but not right:
m = m.Replace(@"\r\n", "
");
m = m.Replace(@"\n", "
");
//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>";
I use this references, but not solution
Interpreting newlines with xsl:text?
XSLT Replace functi开发者_如何学编程on not found
The replace function is only available in XSLT version 2.0, not in version 1.0 which is what Visual Studio uses. Just because you've specified version="2.0" doesn't mean that Visual Studio supports it.
I use this like the last reference, but I get error:
<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="<br/>"/>
</xsl:call-template>
suggestions, any sample code works ?
The call template above looks OK, you just need the template to go with it!
<!-- 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>
There are two problems here:
You should not try to replace CRLF -- such a string isn't present in the text. The reason for this is that any compliant XML parser normalizes the text nodes by replacing any CR+LF combination with a single LF (


). The W3C XML Specification says: "To simplify the tasks of applications, wherever an external parsed entity or the literal entity value of an internal parsed entity contains either the literal two-character sequence "#xD#xA" or a standalone literal #xD, an XML processor must pass to the application the single character #xA. (This behavior can conveniently be produced by normalizing all line breaks to #xA on input, before parsing.) "The replacement shouldn't be a string. It should be a node --
<br />
.
Fixing these two problems is easy:
<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, '
')">
<xsl:value-of select=
"substring-before($pText, '
')"/>
<br />
<xsl:call-template name="replaceNL">
<xsl:with-param name="pText" select=
"substring-after($pText, '
')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$pText"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on this XML document:
<Exception>
<Description>Quite common error:
Missing '('
</Description>
<Message>Error1001:
Syntax error 2002
</Message>
<DateTime>localTimeString</DateTime>
</Exception>
the wanted, correct result is produced:
<Exception>
<Description>Quite common error:<br/> Missing '('<br/> </Description>
<Message>Error1001:<br/> Syntax error 2002<br/> </Message>
<DateTime>localTimeString</DateTime>
</Exception>
I had to write database data to an xml file and read it back from the xml file, using LINQ to XML. Some fields in a record were themselves xml strings complete with \r characters. These had to remain intact. I spent days trying to find something that would work, but it seems Microsoft was by design converting \r to \n.
The following solution works for me:
To write a loaded XDocument to the XML file keeping \r intact, where xDoc is an XDocument and filePath is a string:
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings
{ NewLineHandling = NewLineHandling.None, Indent = true };
using (XmlWriter xmlWriter = XmlWriter.Create(filePath, xmlWriterSettings))
{
xDoc.Save(xmlWriter);
xmlWriter.Flush();
}
To read an XML file into an XElement keeping \r intact:
using (XmlTextReader xmlTextReader = new XmlTextReader(filePath)
{ WhitespaceHandling = WhitespaceHandling.Significant })
{
xmlTextReader.MoveToContent();
xDatabaseElement = XElement.Load(xmlTextReader);
}
精彩评论