[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

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


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">
    <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>


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

</xsl:stylesheet>


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 = "http://www.w3.org/1999/XSL/Transform" 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:element>
	</xsl:element>
</xsl:template>

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

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


</xsl:transform>




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



Vish.


_________________________________________________________________
Add photos to your messages with MSN 8. Get 2 months FREE*. http://join.msn.com/?page=features/featuredemail



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




Current Thread
Keywords