Замените \ r \ n переводы строк, используя XSLT и .NET C # VS 2008 - PullRequest
3 голосов
/ 22 августа 2010

Я использую VS 2008, .net 3.5 для создания html-страницы с использованием XSLT.

У меня есть Сообщение, которое содержит \ r \ n (новые строки)

Я использую это в XSL-файле:

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

Мне нужно заменить \ r \ n на <br/> в xsl.Я видел несколько ссылок, но не нашел решения для своей проблемы:

Я использую этот код 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>";

Я использую эти ссылки, ноне решение

Интерпретация новых строк с помощью xsl: text?

XSLT Функция замены не найдена

Функция замены доступна тольков XSLT версии 2.0, а не в версии 1.0, которая используется Visual Studio.То, что вы указали версию = "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>

подсказки, любой пример кода работает?

Ответы [ 3 ]

8 голосов
/ 22 августа 2010

Вышеуказанный шаблон вызова выглядит нормально, вам просто нужен шаблон, чтобы его использовать!

<!-- 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>
5 голосов
/ 22 августа 2010

Здесь есть две проблемы :

  1. Вы не должны пытаться заменить CRLF - такая строка отсутствует втекст.Причина этого заключается в том, что любой совместимый синтаксический анализатор XML нормализует текстовые узлы, заменяя любую комбинацию CR + LF одним LF (&#xA). W3C XML-спецификация гласит: « Для упрощения задач приложений, где внешняя проанализированная сущность или значение литеральной сущности внутренней анализируемой сущности содержат либо буквенноепоследовательность символов "# xD # xA" или автономный литерал #xD, процессор XML должен передать приложению один символ #xA. (Такое поведение удобно получить, нормализуя все разрывы строк в #xA при вводе, перед анализом.)"

  2. Замена не должна быть строкой .Это должен быть узел - <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 голосов
/ 16 августа 2011

Мне пришлось записать данные базы данных в файл XML и прочитать их обратно из файла XML, используя LINQ to XML.Некоторые поля в записи сами были строками xml с символами \ r.Они должны были остаться нетронутыми.Я потратил несколько дней, пытаясь найти что-то, что бы работало, но, похоже, Microsoft задумал конвертировать \ r в \ n.

Для меня работает следующее решение:

Чтобы записать загруженный XDocument в файл XML, оставив неизменным \ r, где xDoc - это XDocument, а filePath - строка:

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);
}
...