5

i have TextBox to take comment from user, comments will be saved into XML file the problem is when i write a text have enter key (new line ) it will save into the xml in the right way like this

            <comment>
              sdagsg
               fag
                fdhfdhgf
              </comment>

but when i read from the xml looks like this " sdagsg fag fdhfdhgf"

           string strXstFile = Server.MapPath(@"~/TopicAndComments.xsl");
        XslCompiledTransform x = new XslCompiledTransform();

        // Load the XML 
        XPathDocument doc = new XPathDocument(Server.MapPath(@"~/TopicAndComments.xml"));

        // Load the style sheet.
        XslCompiledTransform xslt = new XslCompiledTransform();
        xslt.Load(strXstFile);

        MemoryStream ms = new MemoryStream();
        XmlTextWriter writer = new XmlTextWriter(ms, Encoding.ASCII);
        StreamReader rd = new StreamReader(ms);
        //Pass Topic ID to XSL file
        XsltArgumentList xslArg = new XsltArgumentList();
        xslArg.AddParam("TopicID", "", HiddenField_SelectedTopicID.Value.ToString());
        xslt.Transform(doc, xslArg, writer);

        ms.Position = 0;
        strHtml = rd.ReadToEnd();
        rd.Close();
        ms.Close();
patmortech
  • 10,139
  • 5
  • 38
  • 50
fatma
  • 51
  • 1
  • 4
  • 1
    How do you read from the XML? What do you do with the result of this reading? – Darin Dimitrov Sep 03 '11 at 09:59
  • possible duplicate of: http://stackoverflow.com/questions/5160632/escaping-new-line-characters-with-xmldocument – Davide Piras Sep 03 '11 at 10:35
  • Is that problem really related to XSLT? I suspect, as you have also tagged the question as ASP.NET, that you send the string you have as part of an HTML document to a browser and that you simply experience how browsers render HTML, white space is collapsed into spaces. Depending on your needs there might be nothing wrong with your XML or XSLT, you would simply need to make sure you don't get the normal HTML rendering, but rather stuff the string into an HTML `pre` element (http://www.w3.org/TR/html4/struct/text.html#edef-PRE) and that way white space is not collapsed into spaces. – Martin Honnen Sep 03 '11 at 10:59
  • Good question, +1. See my answer for two complete, short and easy XSLT solutions. :) – Dimitre Novatchev Sep 03 '11 at 16:10

4 Answers4

2

There is nothing wrong with the read of the XML file. XML is not sensitive to white space.

When you want some parts in XML to not follow all the XML rules and be a bit special, you use a so-called CDATA section. This is what you should be using when "saving" the data of the user.

See one way of how to do it in C#. The way you write XML may have a different equivalent:
http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.createcdatasection.aspx

And I think I agree with Davide Piras in his comment on the question. I think you are having the same issue as Escaping new-line characters with XmlDocument, and hence picked the favorite answer to me from there.

Community
  • 1
  • 1
Meligy
  • 35,654
  • 11
  • 85
  • 109
0

When your xml is parsed it gives the following DOM tree:

Original xml:

            <comment>
              sdagsg
               fag
                fdhfdhgf
              </comment>

Generated DOM tree:

|- NODE_DOCUMENT #document ""
  |- NODE_ELEMENT comment ""
    |- NODE_TEXT #text "\n              sdagsg\n               fag\n                fdhfdhgf\n              "

So the carriage returns are in the XML document.

When i use an MXXMLWriter to convert the XML back into text, i get following XML fragment:

<comment>
              sdagsg
               fag
                fdhfdhgf
              </comment>

So you can get your original XML, with all the embedded whitespace and linebreaks.

The issue you're having is that you want to display the XML as HTML. There are a number of issues with that.

If you blindly try to output the XML inside HTML:

<P><comment>
              sdagsg
               fag
                fdhfdhgf
              </comment></P>

Then nothing appears. The html parser doesn't recognize the <comment> element. Browsers are required to not render any elements they don't recognize.

The first fix one might try, is escape the < and > characters, as you are required to do, with &lt; and &gt;:

<P>&lt;comment&gt;
              sdagsg
               fag
                fdhfdhgf
              &lt;/comment&gt;</P>

This now renders in a browser, but renders as:

<comment> sdagsg fag fdhfdhgf </comment>

The reason for this is that the browser is required to collapse whitespace (e.g, tab, space, linebreak) into a single space.

There are two ways you can handle this. First is to put the "pre-formatted" xml into a preformatted (PRE) html element:

<PRE>&lt;comment&gt;
                  sdagsg
                   fag
                    fdhfdhgf
                  &lt;/comment&gt;</PRE>

This gives the output in HTML:

<comment>
                  sdagsg
                   fag
                    fdhfdhgf
                  </comment>

The other, more complicated, solution is to work with HTML, and present the HTML you wish. If you want to maintain all the whitespace (and not have the browser collapse it), then you must convert it explicitly into non-breaking space characters, by replacing "" with "&nbsp;":

<P>&lt;comment&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sdagsg
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fag
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fdhfdhgf
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/comment&gt;</P>

And you also must expliditely have line breaks by converting every "CRLF" into "<BR>":

<P>&lt;comment&gt;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sdagsg<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fag<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fdhfdhgf<BR>

And now you have HTML that preserves your spaces and carriage returns:

<comment>
                  sdagsg
                   fag
                    fdhfdhgf
                  </comment>


But can XSL do it?

i don't know.

XSL may be an NP Turing-complete language, but i don't know if it can:

String html = DocumentToString(xmlDocument);
html = StringReplace(html, "<", "&lt;");
html = StringReplace(html, ">", "&gt;");
html = StringReplace(html, " ", "&nbsp;");
html = StringReplace(html, "\r\n", "<BR>");
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
  • Of course, such text generation can be done with XSLT (however you misunderstood the question -- the OP wants only to display the text). See for example the code of the **XPath Visualizer**: at http://www.huttar.net/dimitre/XPV/TopXML-XPV.html – Dimitre Novatchev Sep 03 '11 at 16:08
0

This transformation:

<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="text()" name="replaceNL">
   <xsl:param name="pText" select="."/>

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

when applied on the provided XML document:

<comment>
   sdagsg
     fag
      fdhfdhgf
</comment>

produces an HTML result with the wanted properties:

<br/>   sdagsg<br/>     fag<br/>      fdhfdhgf<br/>

and it displays in the browser as:


sdagsg
fag
fdhfdhgf

and if you want to preserve even the whitespace, this can be done by a slight modification of the above transformation:

<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="text()" name="replaceNL">
   <xsl:param name="pText" select=
    "translate(., ' ', '&#160;')"/>

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

The result now has every space character replaced by a non-breaking space and in the browser it displays as:


   sdagsg
     fag
      fdhfdhgf

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
0

finally i found the solution the solution is to replace xml space to html space after html generated i add this

    strHtml = strHtml.Replace("&lt;br/&gt;", "<br/>");

at the end of the method before closing the stream reader

fatma
  • 51
  • 1
  • 4