MSXML: preserve whitespace in XML

In short: I would like to preserve the whitespaces in XML. How is that done with MSXML?

The long version:

I am building a CMS where I store data in XML files.

The stylesheets (CSS) are stores in a XML file and called with an ASP-file on the output page. Like this: <link rel="stylesheet" type="text/css" href="css.asp?id=1" />

css.asp:

set xmldoc = Server.CreateObject("Msxml.DOMDocument")
xmldoc.async = false
xmldoc.load(Server.MapPath("stylesheets.xml"))
Set oNode = xmldoc.documentElement.SelectSingleNode("//stylesheet[@id='" & Request("id") & "']")
response.write oNode.SelectSingleNode(".//screen").text

The problem is that the MSXML parser removes all whitespaces and css like this:

body {  
  background : rgb(255,255,255);  
  }
p {       
  font-family: Arial;  
  }       

Becomes:

body { background : rgb(255,255,255);} p { font-family: Arial; }

Which the browser doesn't understand. So I need to preserve the whitespaces. But how?

I have tried to search the internet and found different solutions but can't seem to get it to work. Hope somebody can help me.

Cheers,

Andreas

AndreasAAsked:
Who is Participating?
 
dfiala13Commented:
OK,
I have some good news...
The whitespace is preserved perfectly in the source when you output the document.

The bad news...
Doesn't matter what the source looks like, ie is going to flatten out your elements.

Here's the XML I used....

<?xml version="1.0" encoding="iso-8859-1"?>
<css count="1" nextid="2" foldercount="1" foldernextid="2">
  <folders>
    <folder id="1">
      <title>My Stylesheet</title>
         <folders>
        <stylesheets>
          <stylesheet id="1" rights="">
            <title>Indfødte folks</title>
            <mediatypes>
              <screen>
              body {  
  background : rgb(255,255,255);  
  }
p {      
  font-family: Arial;  
  }  
              </screen>
            </mediatypes>
          </stylesheet>
          </stylesheets>
        </folders>
      </folder>
   </folders>
</css>

Here's the asp page  I used.  Notice it can take two paths depending on the query param "Raw", one where I write out the document directly, the second where I transform it with a stylesheet.

<% Dim xmlDoc
Dim xslDoc
Dim xslt
dim xslProc
set xmlDoc = Server.CreateObject("MSXML2.DOMDocument.4.0")
set xslDoc = Server.CreateObject("Msxml2.FreeThreadedDOMDocument.4.0")
xmlDoc.PreserveWhiteSpace=true
xmlDoc.Load("c:\inetpub\wwwroot\test\ct\css.xml")

if Request.QueryString("Raw") then
      response.Write(xmlDoc.xml)
else

      xslDoc.Load("c:\inetpub\wwwroot\test\sty\css.xslt")
      
      set xslt = Server.CreateObject("Msxml2.XSLTemplate.4.0")
      set xslt.stylesheet = xslDoc
        
      set xslProc = xslt.createProcessor()
      xslProc.input = xmlDoc
       xslProc.transform()
      
      response.Write(xslProc.output)
End if
%>

Here's the "Raw" source (what the actual XML output looks like):

<?xml version="1.0"?>
<css count="1" nextid="2" foldercount="1" foldernextid="2">
  <folders>
    <folder id="1">
      <title>My Stylesheet</title>
         <folders>
        <stylesheets>
          <stylesheet id="1" rights="">
            <title>Indfødte folks</title>
            <mediatypes>
              <screen>
              body {  
  background : rgb(255,255,255);  
  }
p {      
  font-family: Arial;  
  }  
              </screen>
            </mediatypes>
          </stylesheet>
          </stylesheets>
        </folders>
      </folder>
   </folders>
</css>

Which in fact looks the same as the transformed output.

However, if I turned off xmlDoc.preserveWhitespace and transformed, this was the output...

<?xml version="1.0" standalone="yes"?>
<css count="1" nextid="2" foldercount="1" foldernextid="2">
<folders>
<folder id="1">
<title>My Stylesheet</title>
<folders>
<stylesheets>
<stylesheet id="1" rights="">
<title>Indfødte folks</title>
<mediatypes>
<screen>
              body {  
  background : rgb(255,255,255);  
  }
p {      
  font-family: Arial;  
  }  
              </screen>
</mediatypes>
</stylesheet>
</stylesheets>
</folders>
</folder>
</folders>
</css>

The one thing to note, is that in all the outputs, the <screen> elements contents were always rendered with the whitespace preserved.  So the fact that IE is flattening out the element whenit displays the file is not an issue with the underlying source, but just with IE.

So taking it little farther and just outputting the single node instead of the whole doe

Set oNode = xmldoc.documentElement.SelectSingleNode("//stylesheet[@id='" & Request("id") & "']")
response.write oNode.SelectSingleNode(".//screen").text

Actually returns...

body {  
  background : rgb(255,255,255);  
  }
p {      
  font-family: Arial;  
  }

which IE does flatten out when viewing, but as with the examples above, the whitespace is actually preserved.  So I bet if you look at the actual source of the page returned bu your current asp page you will find the same nicely preserved output



0
 
conorjCommented:
change

xmldoc.async = false
xmldoc.load(Server.MapPath("stylesheets.xml"))

to

xmldoc.async = false
xmldoc.preserveWhiteSpace = True
xmldoc.load(Server.MapPath("stylesheets.xml"))

and your whitespace will be preserved.

Hope this helps.

rgds,
Conor.
0
 
AndreasAAuthor Commented:
Conor: I have allready tried that. It didn't work :-(
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
dfiala13Commented:
What's your raw XML look like with tags, etc.?
0
 
AndreasAAuthor Commented:
<?xml version="1.0" encoding="iso-8859-1"?>
<css count="1" nextid="2" foldercount="1" foldernextid="2">
  <folders>
    <folder id="1">
      <title>My Stylesheet</title>
      <folders/>
        <stylesheets>
          <stylesheet id="1" rights="">
            <title>Indfødte folks</title>
            <mediatypes>
              <screen>
              </screen
                ...
            </mediatypes>
          </stylesheet>
        </folders>
      </folder>
   </folders>
</css>
0
 
dfiala13Commented:
So the screen tag looks like this?
<screen>
body {  
  background : rgb(255,255,255);  
  }
p {      
  font-family: Arial;  
  }      
</screen>
0
 
AndreasAAuthor Commented:
Yes and no...

When I look at my XML file in IE, the <screen> node looks like this (no whitespace):

body { background : rgb(255,255,255);} p { font-family: Arial; }


When I open the node in a textarea it looks like this (with withspace):

body {  
  background : rgb(255,255,255);  
  }
p {      
  font-family: Arial;  
  }      
0
 
dfiala13Commented:
>>When I open the node in a textarea it looks like this (with withspace):

body {  
  background : rgb(255,255,255);  
  }
p {      
  font-family: Arial;  
  }    

Which is what you want it to look like in IE, yes?
0
 
AndreasAAuthor Commented:
exactlly!
0
 
pmsyyzCommented:
Have you tried adding:

xml:space="preserve"

to your XML document's root element?

Perhaps the MSXML parser is aware of it and will obey it.

http://www.w3.org/TR/REC-xml/#sec-white-space
0
 
AndreasAAuthor Commented:
dfiala13: Thanks for an excellent answer. You are absolutely correct, its IE that flattens the stylesheet and the whitespace are actually preserved. It works beautifully :-)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.