only for RuBoard |
xsl:preserve-space specifies the elements whose text node children are not to be removed from the result tree if they contain only spaces.
XSLT parsers will remove text nodes from the constructed source tree if their content contains only spaces. It does not strip text nodes unless their content contains only spaces. The xsl:preserve-space element allows for the preservation of those child text nodes so they are still contained in the source tree upon parsing.
The MSXML Parser requires loading the source document into a DOM tree before parsing. The act of loading the source into the DOM may strip significant white space before the stylesheet is rendered, so the xsl:preserve-space might seem to have no effect. To preserve significant white space when initially loading the source tree into the DOM, set the preserveWhiteSpace property of the DomDocument object to True before loading the XML.
The .NET parser handles white space differently. A property of the XmlReader is WhiteSpaceHandling , which is one of the WhiteSpaceHandling enumeration members . This is covered in detail in Chapter 3, "XML Presentation."
Attribute Name | Enforced | Description | Values |
---|---|---|---|
Elements | Required | The list of elements that are to have text node children preserved if they contain only spaces. | NMTokens |
Consider the following document, source.xml :
<?xml version="1.0" encoding="UTF-8" ?> <links> <link> </link> <link> </link> <link> </link> </links>
We experiment with different combinations of xsl:preserve-space to show the effects of each setting. We begin with a simple stylesheet that does not preserve any white space. This stylesheet is trans.xslt . The stylesheet simply displays the number of spaces for each node in the selected nodes:
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" /> <xsl:template match="/"> <xsl:for-each select="links/link"> <xsl:text>[</xsl:text> <xsl:value-of select="string-length(.)" /> <xsl:text>]</xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>
The MSXML Parser handles white space somewhat differently than other parsers. To demonstrate this, parse the document using MSXML 4.0 with Visual Basic 6. You are only using VB6 here as a control to avoid issues where the browser might not have the correct version installed:
Option Explicit Private Sub Command1_Click() Dim xml As New MSXML2.DOMDocument40 Dim trans As New MSXML2.DOMDocument40 Dim fso As New Scripting.FileSystemObject Dim strm As Scripting.TextStream On Error GoTo eh xml.Load "c:\temp\source.xml" trans.Load "c:\temp\trans.xslt" Set strm = fso.OpenTextFile("c:\outfile.txt", ForWriting, True) strm.Write xml.transformNode(trans) strm.Close Set xml = Nothing Set trans = Nothing Exit Sub eh: Debug.Assert False strm.Close Set strm = Nothing Set fso = Nothing Set trans = Nothing Set xml = Nothing End Sub
This results in the following output in the file outfile.txt :
<?xml version="1.0"?>[1][1][1]
To preserve white space, you need to preserve white space in the source XML DOM and within the stylsheet. To do this, alter the stylesheet to include the xsl:preserve-space element:
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:preserve-space elements="link"/> <xsl:output method="xml" version="1.0" /> <xsl:template match="/"> <xsl:for-each select="links/link"> <xsl:text>[</xsl:text> <xsl:value-of select="string-length(.)" /> <xsl:text>]</xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>
Also alter the code for MSXML by setting the preserveWhiteSpace property to True prior to loading the XML source:
On Error GoTo eh xml.preserveWhitespace = True xml.Load "c:\temp\source.xml"
This combination of steps yields the expected result.
[5][13][21]
To achieve the same result in .NET, you again need to preserve white space in the parser prior to loading the document. You can achieve this by using an XmlDocument object to load the source XML and set the PreserveWhitespace property of the XmlDocument object to True:
Sub Main() Dim xsltReader As System.Xml.XmlTextReader = New System.Xml.XmlTextReader("c:\temp\trans.xslt") Dim xsltdoc As System.Xml.XPath.XPathDocument = New System.Xml.XPath.XPathDocument(xsltReader, XmlSpace.Preserve) Dim xmldoc As System.Xml.XmlDocument = New System.Xml.XmlDocument() 'Preserve whitespace and then load the xml source xmldoc.PreserveWhitespace = True xmldoc.Load("c:\temp\source.xml") 'Create the XslTransform object and load the stylesheet. Dim xslt As XslTransform = New XslTransform() xslt.Load(xsltdoc) 'Create an XmlTextWriter which outputs to the console. Dim writer As XmlTextWriter = New XmlTextWriter(Console.Out) 'Transform the file and send the output to the console. xslt.Transform(xmldoc, Nothing, writer) writer.Close() End Sub
The output in the console window is the same as this result:
[5][13][21]
Xsl:stylesheet, xsl:transform
None.
only for RuBoard |