• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 342
  • Last Modified:

using <xsl:preserve-space elements="Client_Comment" /> is preserving font

a snippet of the code im using in an xsl stylesheet is:
<xsl:preserve-space elements="Client_Comment" />
    <xsl:output method="html"/>

and then:
<pre><xsl:value-of select="./@Client_Comment"/></pre>

I have done this to preserve carriage returns etc but it seems to be preserving the font and ignroing my style changes.

Is there anyway around this?
0
scm0sml
Asked:
scm0sml
  • 4
  • 3
1 Solution
 
Geert BormansInformation ArchitectCommented:
Hi scm0sml,
> I have done this to preserve carriage returns

you can't preserve carriage returns in an attribute value.
According to the XML specification,
each XML attribute must be normalized before being sent to the application
Normalisation includes replacing each white-space character with a space
The carriage return is gone before it reaches the XSLT processor

If you want to maintain carriage returns you have to make the string element content

Cheers!
0
 
scm0smlAuthor Commented:
so in english lol?
0
 
Geert BormansInformation ArchitectCommented:
well,

the XML specification says that a parser must normalize an attribute
before sending it to an application
This means that the parser that gives the parsed XML to the XSLT processor
must do some normalization steps on the attribute value
one of these steps is that every white-space character (tab, carriage return, line-feed, space,...)
will be replaced bay a space
(for a reference read http://www.w3.org/TR/REC-xml/#AVNormalize)

this means that the XSLT processor will never know that a space in an attribute value,
used to be a carriage return,
so whatever you do in your XSLT program, you can't bring the carriage return back

that is why there is a
<xsl:preserve-space elements="..." />
and not
<xsl:preserve-space attributes="..." />
because that makes no sense

the spaces that remain are automatically preserved

So, if you really want to preserve the carriage-returns
you will have to put them in an element instead of an attribute

hope this now explains it well enough

I hope you have access to the source XML file
and you can change it at the source
If you need to convert the attributes to elements
you will have to do that using text processing techniques,
because if you use XML techniques (whatever, DOM, SAX, XSLT,...)
there will be a parser first, and the parser will normalize the attribute value
... back to square root one

I can write you a small Ruby program that does the transform for you,
if you want to

cheers

Geert

Geert
0
Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

 
scm0smlAuthor Commented:
is there any resource u recommend for converting the attributes to elements?
0
 
scm0smlAuthor Commented:
how would i go about implementing this ruby program?

i'm viewing the xml in xmlspy incase thats of any use.
0
 
Geert BormansInformation ArchitectCommented:
I will show you over the weekend, if that is OK for you
0
 
Geert BormansInformation ArchitectCommented:
Hi,

switching machines took a bit longer than expected

I have a little Ruby program here that takes the attribute
and puts it in an element with the same name, immedeatly after the opening tag
You can now preserve the spaces in XSLT

what you should do
- download ruby 1.8 and install it (http://www.ruby-lang.org/en/downloads/)
- save the below snippet as a file attr2elem.rb
- run this command-line: ruby attr2elem.rb source.xml > result.xml

note that the source and result xml files can have other names

Here is what you can do then
- get the original XML, transform with the ruby program and then transform in a second step using XSLT with preserve spaces

The Ruby program:
#============
class ReplaceList
      def initialize
            @for_element = ""
      end
      def evaluate_tag_content(str)
            re = /((Client_Comment)=(["'])(.*?)\3)/m
            if md = re.match(str)
                  @for_element = "<" + md[2] + ">" + md[4] + "</" + md[2] + ">"
              "#{ unless md.pre_match.nil?; md.pre_match; else ''; end; }" +
                  "#{ unless md.post_match.nil?; md.post_match; else ''; end; }"
             else
                  @for_element = ""
                   str
            end
      end
      def extract_tags(str)
            re = /<([^>]+?)>/
            if md = re.match(str)
              "#{ unless md.pre_match.nil?; md.pre_match; else ''; end; }" +
                  '<' + evaluate_tag_content(md[1]) + '>' + @for_element +
                  "#{ unless md.post_match.nil?; extract_tags(md.post_match); else ''; end; }"
            end
      end
end

lines = Array.new
while line = gets
            lines << line
end

tagger = ReplaceList.new
puts tagger.extract_tags(lines.join)

0

Featured Post

2018 Annual Membership Survey

Here at Experts Exchange, we strive to give members the best experience. Help us improve the site by taking this survey today! (Bonus: Be entered to win a great tech prize for participating!)

  • 4
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now