Re: [xsl] Newline problems

Subject: Re: [xsl] Newline problems
From: "Vishwajit Pantvaidya" <pantvaidya@xxxxxxxxxxx>
Date: Wed, 07 May 2003 16:47:38 -0700
Thanks Mike, this to me seems like a novel way of doing it. I guess it would be good to use this approach when there are very few elements from the src xml that are not needed in the output xml i.e. I do not have too many templates to ignore elements (just like you have here for BILL_TO_ADDRESS3).

Here is a template-based approach. I added comments so you would better understand what is going on. Couple of things: 1. Any time you use disable-output-escaping, you'd better have a really good reason. The utility of producing an empty DOCTYPE is a mystery to me, but it's what you wanted, so... See, normally you let the serializer create the DOCTYPE for you; you just put doctype-public and/or doctype-system attributes in the xsl:output element to signal what you want, as long as you don't need to write an internal DTD subset. 2. Maybe you have a good reason for using template modes. They're not needed for your example, though.

As I believe I mentioned, the DOCTYPE, though empty is needed by the target system.
About the template modes, they came in the sheet I inherited. I just retained them as I had a very limited mandate and I am only beginning to learn xsl, so I did not want to touch any thing that I was not sure of.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="";>

<xsl:output method="xml" indent="yes" encoding="utf-8"/>

  <xsl:template match="/">
      since doctype-public="" doctype-system="" in xsl:output
      doesn't uniformly produce an empty DOCTYPE across all
      XSLT processors, we'll use d-o-e
    <xsl:value-of disable-output-escaping="yes"
      select="'&lt;DOCTYPE Order&gt;
    <!-- go process the root node's children -->

Just an addition - I had to add an "!" before the DOCTYPE.

  <!-- when processing a Quote element, generate an Order element
  that contains the result of processing the Quote element's children -->
  <xsl:template match="Quote">

  <!-- when processing an Info element, generate another Info element
  that contains the result of processing the original's children -->
  <xsl:template match="Info">

<!-- when processing an 'attribute' element that has a 'name' child
whose normalized string-value is 'BILL_TO_ADDRESS3', do nothing -->
<xsl:template match="attribute[normalize-space(name)='BILL_TO_ADDRESS3']"/>

  <!-- when processing any other 'attribute' element, generate an
  element whose name is the normalized string-value of the 'attribute'
  element's 'name' element child, and its contents shall be the result
  of processing the 'atomicValue' children of the 'attribute' element -->
  <xsl:template match="attribute">
    <xsl:element name="{normalize-space(name)}">
      <xsl:apply-templates select="atomicValue"/>

  <!-- when processing a text node, generate a new text node
    using the normalized value of the original node -->
  <xsl:template match="text()">
    <xsl:value-of select="normalize-space(.)"/>

When does this overridden text template get called. We do not seem to have any templates that explicitly match text(). Does it get auto called when any text is encountered?

  <!-- don't forget that there is a built-in template that we're
     relying on to handle the atomicValue elements (and any others
     that we didn't provide explicit templates for): it just results
     in the processing of the element's children; nothing is
     generated. It looks like this:
      <xsl:template match="*">


Just for info, I am also posting here the other approach that Lars suggested:

<?xml version = "1.0" encoding = "UTF-8"?>
<xsl:transform xmlns:xsl = ""; version = "1.0">

<xsl:template match = "Quote">
<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE Order&gt;</xsl:text>
	<xsl:element name = "Order">
		<xsl:element name ="Info">
			<xsl:apply-templates mode = "Attribs" select = "/Quote/Info"/>

<xsl:template mode = "Attribs" match = "Info">
 <xsl:call-template name="atomicValue">
	<xsl:with-param name="AVname" select="'BILL_TO_ADDRESS2'" />
 <xsl:call-template name="atomicValue">
	<xsl:with-param name="AVname" select="'PO_NUMBER'" />

<xsl:template name="atomicValue">
<xsl:param name="AVname" select="''" />
<xsl:element name="{$AVname}">
<xsl:value-of select="attribute/atomicValue[normalize-space(../name)=$AVname]"/>


Thanks Mike, Lars, Michael, David and all others who helped out.


Add photos to your messages with MSN 8. Get 2 months FREE*.

XSL-List info and archive:

Current Thread