unwanted blank lines in output when using xalan

Discussion in 'XML' started by Jeff Calico, Feb 7, 2006.

  1. Jeff Calico

    Jeff Calico Guest

    Hello everyone

    I am transforming an XML document to text, basically only outputting
    a small portion of it. When I run the following XSLT via Xalan's
    processor,
    I get a bunch of unwanted blank lines in the output.
    Here is a simplified XML and XSLT:
    (Note the problem does not happen when testing in XMLSpy)

    - - - - - - - - - - - - - - - - - - - - - - - -
    ....
    <AAA>
    <anne anneId="blah" annName="blah"/>
    <anne anneId="blah" annName="blah"/>
    </AAA>
    <BBB>
    junk
    </BBB>
    <CCC>
    junk
    </CCC>
    ....
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - -
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE stylesheet [
    <!ENTITY cr "<xsl:text>
    </xsl:text>">
    ]>

    <xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:eek:utput method="text" version="1.0" encoding="UTF-8" />

    <xsl:template match="/AAA/anne">
    &cr;
    <xsl:value-of select="@anneId"/> <xsl:text> </xsl:text>
    <xsl:value-of select="@anneName"/>
    </xsl:template>
    </xsl:stylesheet>

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - - -

    I end up with a vast segment of blank lines before and after my data.
    It is as if every time the processor reads any element, it's default
    behaviour is to output a blank line, and when it actually matches with
    the elements I want, then it behaves fine. If I put in "do nothing"
    matches for all the other top level elements, then the number of blank
    lines
    is cut down, but not entirely eliminated:

    <xsl:template match="/BBB"></xsl:template>
    <xsl:template match="/CCC"></xsl:template>

    NOTE: The "cr" entity is necessary to put *desired* blank lines between
    my
    lines of output data, and it shouldn't be triggered unless I match on
    /AAA/anne right?

    Does anyone know why I get these blanks, and how I can totally
    eliminate them?

    thanks,
    Jeff
    Jeff Calico, Feb 7, 2006
    #1
    1. Advertising

  2. Remember, whitespace in the source document is a legitimate part of the
    document!

    Your stylesheet provides an explicit rule for template for the AAA/anne
    nodes... but it doesn't provide a template for the root element
    (match="/"), which is where processing starts. That means your
    stylesheet starts by applying the built-in default templates:

    <xsl:template match="*|/">
    <xsl:apply-templates/>
    </xsl:template>
    <xsl:template match="text()|@*">
    <xsl:value-of select="."/>
    </xsl:template>

    So, given your input document:

    <doc>
    <AAA>
    <anne anneId="blah" annName="blah"/>
    <anne anneId="blah" annName="blah"/>
    </AAA>
    <BBB>
    junk
    </BBB>
    <CCC>
    junk
    </CCC>
    </doc>

    We first match the root node as "/". The built-in template processes
    this by running apply-templates against its the children.

    That takes us to <doc>. It matches as "*", so we do another level of
    apply-templates against the children.

    The first child of <doc> is the whitespace text node between <doc> and
    <AAA>. This matches as text(), and we output its value -- a newline.

    The next child is <AAA>. That matches as "*", so we start applying
    templates to its content.

    The next child is whitespace again -- between <AAA> and <anne> -- so we
    output it. That's another blank line.

    And so on. Basically, because you're letting the defaults run, you're
    going to get most of the text content of the source document, including
    all its newlines.

    The best fix is to write your own match="/" template which takes you
    more directly to what you want to process. If all you care about is
    those <anne> elements, I'd suggest you try adding this to override the
    builtin default and take you right to the nodes you want to see:

    <xsl:template match="/">
    <xsl:apply-templates select="/AAA/anne">
    </xsl:template>

    By the way, note that your template for the <anne> elements can just say
    match="anne". You only need to say "/AAA/anne" if you need to
    distinguish these from <anne> elements that might be encountered
    elsewhere in the document.
    Joe Kesselman, Feb 8, 2006
    #2
    1. Advertising

  3. Jeff Calico

    Jeff Calico Guest

    Joe Kesselman wrote:
    > Remember, whitespace in the source document is a legitimate part of the
    > document!


    [snip]

    Thanks, Joe! That was a very informative discussion, and the result
    works
    great!

    > <xsl:template match="/">
    > <xsl:apply-templates select="/AAA/anne">
    > </xsl:template>
    >
    > By the way, note that your template for the <anne> elements can just say
    > match="anne". You only need to say "/AAA/anne" if you need to
    > distinguish these from <anne> elements that might be encountered
    > elsewhere in the document.


    I couldn't get it to work if I just specified the final element "anne"
    (I suppose I could
    do "//anne", but anyway the full path works, and I had the idea that
    doing it that way
    saved the XSLT processor from having to search through the DOM tree...

    --Jeff
    Jeff Calico, Feb 8, 2006
    #3
  4. >>By the way, note that your template for the <anne> elements can just say
    >>match="anne". You only need to say "/AAA/anne" if you need to
    >>distinguish these from <anne> elements that might be encountered
    >>elsewhere in the document.

    ....
    > I had the idea that doing it that way
    > saved the XSLT processor from having to search through the DOM tree...


    Nope. If anything, you've added work, because now the processor has to
    check that the <anne> element's parent is an <AAA>.

    Select does the search. Match confirms that you've found the ones you're
    interested in.
    Joe Kesselman, Feb 9, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ricky
    Replies:
    1
    Views:
    774
    Joris Gillis
    Oct 17, 2004
  2. cvissy
    Replies:
    0
    Views:
    599
    cvissy
    Nov 16, 2004
  3. Rene van Hoek

    Xalan transform output to string

    Rene van Hoek, Nov 22, 2004, in forum: XML
    Replies:
    1
    Views:
    817
    Rene van Hoek
    Nov 23, 2004
  4. Meikel
    Replies:
    0
    Views:
    473
    Meikel
    Jan 17, 2005
  5. Cah Sableng
    Replies:
    0
    Views:
    230
    Cah Sableng
    Apr 23, 2007
Loading...

Share This Page