Re: [xsl] complex "insert" rules; generalized insert

Subject: Re: [xsl] complex "insert" rules; generalized insert
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Wed, 13 Oct 2004 15:42:41 -0400
Eric,

A quick and dirty solution could work like this ... understand we don't know exactly how general you need it:

<xsl:template match="parent">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:copy-of select="child_a" />
    <xsl:copy-of select="child_b" />
    <xsl:copy-of select="child_c"/>
    <xsl:if test="not(child_c)">
      <child_c/>
    </xsl:if>
    <xsl:copy-of select="child_d" />
    <xsl:copy-of select="child_e" />
  </xsl:copy>
</xsl:template>

Untested....

Cheers,
Wendell

At 02:19 PM 10/13/2004, you wrote:

XSL list:

I'm developing a stylesheet that checks for and inserts missing nodes and/or branches into an existing XML file that I can make minimal assumptions about. The input XML may or may not have any portion of the XML to be added. The order of the inserted nodes is important. Here's an example of the multiple potential input XML files, the desired output, and my attempt at the XSL to do the insert. Goal: to insert "child_c" node under "parent" node.

Potential input #1 (node "child_c" already exists):
===========================================
<parent>
   <child_a></child_a>
   <child_b></child_b>
   <child_c></child_c>
   <child_d></child_d>
   <child_e></child_e>
</parent>

Potential input #2 (node "child_c" doesn't exist):
===========================================
<parent>
   <child_a></child_a>
   <child_b></child_b>
   <child_d></child_d>
   <child_e></child_e>
</parent>

Potential input #3 (node "child_c" doesn't exist, node "child_b" doesn't either):
===========================================
<parent>
<child_a></child_a>
<child_d></child_d>
<child_e></child_e>
</parent>


Potential input #4 (node "child_c" exists, but in wrong location):
===========================================
<parent>
   <child_c></child_c>
   <child_a></child_a>
   <child_b></child_b>
   <child_d></child_d>
   <child_e></child_e>
</parent>

Desired output: (exept "child_b" would be missing in input #3):
===========================================
<parent>
   <child_a></child_a>
   <child_b></child_b>
   <child_c></child_c>
   <child_d></child_d>
   <child_e></child_e>
</parent>

My attempt at the stylesheet:
===========================================
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
       xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" indent="yes"/>

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

<xsl:template match="*[self::child_a or self::child_b or self::child_c or self::child_d or self::child_e][3]">
<!-- if it's not child_c, then add it -->
<xsl:if test="name(.)!='child_c'">
<xsl:element name="child_c">
</xsl:element>
</xsl:if>


   <!-- copy the element no matter what it is -->
   <xsl:copy>
       <xsl:apply-templates select="@*|node()" />
   </xsl:copy>
</xsl:template>

<!-- TEMPLATE: default -->
<xsl:template match="@*|node()">
 <xsl:copy>
   <xsl:apply-templates select="@*|node()" />
 </xsl:copy>
</xsl:template>

</xsl:stylesheet>

This stylesheet only manages to handle inputs #1 and #2 and generates the wrong output on #3 and #4. How would I generize this XSL to handle this insert for all cases?


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