Re: [xsl] Newline problems

Subject: Re: [xsl] Newline problems
From: Mike Brown <mike@xxxxxxxx>
Date: Tue, 6 May 2003 19:15:09 -0600 (MDT)
Vishwajit Pantvaidya wrote:
> > > <Quote>
> > > <Info>
> > > <attribute>
> > > <name>
> > > BILL_TO_ADDRESS3</name>
> > > <atomicValue>PO BOX 1234</atomicValue>
> > > </attribute>
> > > <attribute>
> > > <name>
> > > BILL_TO_ADDRESS2</name>
> > > <atomicValue>MEDICAL CENTER</atomicValue>
> > > </attribute>
> > > <attribute>
> > > <name>
> > > PO_NUMBER</name>
> > > <atomicValue>123456</atomicValue>
> > > </attribute>
> > > </Info>
> > > </Quote>
> [...]
> The output desired is:
> 
> <?xml version="1.0" encoding="UTF-8" ?>
> <!DOCTYPE Order>
> <Order>
> <Info>
> <BILL_TO_ADDRESS2>PO BOX 1234</BILL_TO_ADDRESS2>
> <PO_NUMBER>123456</PO_NUMBER>
> </Info>
> </Order>
> 

Thank you for finally saying what you wanted.

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.

<?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" 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;&#10;'"/>
    <!-- go process the root node's children -->
    <xsl:apply-templates/>
  </xsl:template>

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

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

  <!-- 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"/>
    </xsl:element>
  </xsl:template>

  <!-- 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(.)"/>
  </xsl:template>

  <!-- 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="*">
        <xsl:apply-templates/>
      </xsl:template>
  -->

</xsl:stylesheet>

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread