Where’d My White Space Go?

XSL white space preservation and the Sort method in ADO.NET don't appear to work ... or do they?

asp.netNOW Q&A

LANGUAGES: C#

ASP.NET VERSIONS: 1.0 | 1.1

 

Where'd My White Space Go?

XSL white space preservation and the Sort method in ADO.NET don't appear to work ... or do they?

 

By Josef Finsel

 

Q: I am trying to superclass the XML server control in ASP.NET for use on some of our portal sites to display news and information. The news comes from a SQL Server 2000 database in the form of an XML stream. I created an XSL stylesheet to format the information as HTML. The problem I have pertains to how the control handles significant white space. It apparently ignores significant white space whether I include the <xsl:preserve-space> element in the stylesheet or not. Is this by design? Should I be looking elsewhere for displaying this data on a Web page?

- BC, Seattle, Wash.

 

A: XSL stylesheets are convenient ways to reformat XML, especially when you're retrieving data from SQL Server in XML format (read Asli Bilgin's article, Integrate SQL Server 2000 With XML. Paradoxically, this problem is easy, yet it confusing due to a few layers of indirection.

 

First, look at what happens when .NET processes an XML Document. Here's what Microsoft has to say about white space in an XML Document:

 

"To achieve maximum performance, when a text file is opened with the xmlDoc.load or xmlDoc.loadXML methods (where xmlDoc is an XML DOM document), the parser strips most white space from the file unless specifically directed otherwise; the parser notes within each node whether one or more spaces, tabs, new lines, or carriage returns follow the node in the text by setting a flag [emphasis mine]."

 

(See the article "White Space and the DOM" in the MSDN Library: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/htm/dom_concepts_7mb1.asp.)

 

Now, you might think having the stylesheet flag set to preserve white space will take care of your problems - but this isn't so. Why? The stripping gets done when the document is loaded, which takes place before the stylesheet translation. If you download the source code for this article, you'll find a sample XML file and related XSLT stylesheet. These are used with both examples for this question. LoadDOM1.aspx simply is the XML control on a blank Web page with the XML doc and stylesheet properties filled in. The XML records that contain white space in the form of extra spaces and carriage returns/line feeds are stripped out.

 

The good news is the XML control does nothing more than take an XML doc and stylesheet and spit out the data to a Web page. This all can be handled in a couple of lines of code. This also gives you the opportunity to set the PreserveWhiteSpace property to true, meaning white space won't get stripped out:

 

XmlDocument docXml = new XmlDocument();

docXml.PreserveWhitespace=true;

docXml.Load(Server.MapPath("results.xml"));

XslTransform docXsl = new XslTransform();

docXsl.Load(Server.MapPath("announcements.xslt"));

docXsl.Transform(docXml,null,Response.Output);      

 

Even doing this doesn't guarantee the white space will show up in the browser. This is because most browsers ignore carriage returns/line feeds and extra spaces. This means you need to use HTML tags such as <PRE></PRE>, which keep all formatting intact. So if you want to superclass the XML control, you can use the previous code to create your own control and make PreserveWhiteSpace an option you can set.

 

Q: I want to sort the data stored in DataView, but the result is not correct. Is something wrong with my code?

- TND, via e-mail

 

A: Before I answer this, take a quick look at the code was sent in with this question. It's a very simple piece of code that creates a table, adds two columns, and adds some data:

 

DataSet table = new DataSet();

 // initialize data for the table.

table.Tables.Add();

table.Tables[0].Columns.Add("ID");

table.Tables[0].Columns.Add("Name");

object[] r1 = {"A1", "Dinh"};

object[] r2 = {"A2", "Hung"};

object[] r3 = {"A0", "Uyen"};

table.Tables[0].Rows.Add(r1);

table.Tables[0].Rows.Add(r2);

table.Tables[0].Rows.Add(r3);

// put column 's name to sort

table.Tables[0].DefaultView.Sort = "ID ASC";

table.Tables[0].DefaultView.ApplyDefaultSort=true;

for (int i=0; i<3; i++)

{

  Response.Write(table.Tables[0].Rows[i]["ID"].ToString());

  Response.Write("<BR>");

  }

 

The bolded line is the one in question because it appears to set the sort column to ID, sorted ascending. If you load this code into the page load event, however, it will print out in the same order it was added.

 

The code isn't syntactically wrong, but we're printing out from the table, which is still in the order it was input. To use the DataView's sort capacity, you need to use something that utilizes it: the DataGrid, for instance. If you add a DataGrid to the Web form and bind the table to the grid, the grid will display data in sorted order. If you load ADOSort.aspx, you'll see it loads and sorts the grid fine, but the data printed is unsorted.

 

If you want to get at the sorted data without using a grid, you need to use the DataTable's Select method. The Select method returns an array of DataRows based on filter and sort criteria you supply. There are several ways to use this method. You could supply the filter and sort criteria as parameters to the method, but for this example I'll keep it simple and simply set the Sort property through the DefaultView, as I did in the first example:

 

DataRow[] drArray = table.Tables[0].Select();

for (int i=0; i<drArray.Length; i++)

{

  Response.Write(drArray[i]["ID"].ToString());

  Response.Write("<BR>");

}

 

With the first line of the previous code, I create an array of DataRows to load with the Select method. The DataRow array works the same way a 2-D array would, with the first index pointing to the row and the second pointing to the column - except you can use column names instead of numbers if you'd prefer. You can find the code for this second example in the ADOSort2.aspx.

 

Keep your ASP.NET questions coming to me at [email protected].

 

The sample code in this article is available for download.

 

Josef Finsel is a software developer specializing in .NET and SQL Server with Avanade, the premier global technology integrator for Microsoft solutions in the enterprise. He has published a number of VB, .NET, and SQL Server articles and, when he isn't hanging around the aspnetpro forums, you can find him working on his own take on Shakespeare's classics. He's also author of The Handbook for Reluctant Database Administrators.

 

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish