Re: [xsl] Output the Value of Element without its Child Elements

Subject: Re: [xsl] Output the Value of Element without its Child Elements
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Fri, 15 Jul 2005 12:17:24 -0400
Hi,

At 07:54 PM 7/14/2005, Stuart wrote:
On Thu, 2005-07-14 at 17:21 -0500, Renick, Garrel wrote:
>For example, my XML looks like:
>
>  <STANDARD>
>     <GRADE>Grades Pre-K-2</GRADE>
>     <TOPIC ID="1" >
>       <![CDATA[Students will use the skills and strategies of the
> reading process to comprehend, interpret, evaluate, and appreciate
> what they have read.]]>
>      <TOPIC id="2"><![CDATA[Seek out and enjoy experiences with books
> and other print materials.]]></TOPIC>
>      <!-- there may be many nested subtopics here -->
>    </TOPIC>
>  </STANDARD>

> I would like to output:
>
> 1
> Students will use the skills and strategies of the reading process to
> comprehend, interpret, evaluate, and appreciate what they have read.
> 2
> Seek out and enjoy experiences with books and other print materials.

I suspect you meant id="2" to be ID="2" in your example.

Is this what you want?

<xsl:template match="TOPIC">
  <xsl:value-of select="@ID"/><br/>
  <xsl:value-of select="node()[not(self::TOPIC)]"/>
  <xsl:apply-templates select="./TOPIC"/>
</xsl:template>

This will work, but it is brittle. It's not the XSLT's fault: Stuart's solution is well designed to address the requirement given the source format. It's the source format itself. It works well enough for this problem, but it's not as extensible as it should be.


A simple change, however, and things become much easier to understand, to run, and to extend when requirements become more complex --

<STANDARD>
     <GRADE>Grades Pre-K-2</GRADE>
     <TOPIC ID="1" >
       <DESCRIPTION>Students will use the skills and strategies of the
 reading process to comprehend, interpret, evaluate, and appreciate
 what they have read.</DESCRIPTION>
      <TOPIC id="2">
         <DESCRIPTION>Seek out and enjoy experiences with books
 and other print materials.</DESCRIPTION>
      <!-- there may be many nested subtopics here -->
    </TOPIC>
  </STANDARD>

(Hint: CDATA marked sections are not like ordinary tags, and they don't create elements. You want an element there, not just loose text.)

Then the XSLT becomes:

<xsl:template match="TOPIC">
  <xsl:value-of select="@ID"/><br/>
  <xsl:apply-templates select="DESCRIPTION"/>
  <xsl:apply-templates select="TOPIC"/>
</xsl:template>

or even
<xsl:template match="TOPIC">
  <xsl:value-of select="@ID"/><br/>
  <xsl:apply-templates/>
</xsl:template>

This is better because:

* the description and subtopic are now easily distinguishable by the processor as well as by you
* either topics, or their descriptions, can now be elaborated, if necessary, without having to alter the stylesheet logic or rearrange anything.


NB: XPath "./TOPIC" is effectively the same as XPath "TOPIC". (The latter is short for "child::TOPIC" while the former abbreviates "self::node()/child::TOPIC".)

Finally: those @ID attributes don't have to be maintained by the XML if that's painful. Topic numbering can easily be provided by the XSLT, if called upon.

Cheers,
Wendell


====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ======================================================================

Current Thread