[xsl] PART 3 -THE REVERSE DIRECTION -- Yet still moving elements -- to a new location in a different Result-tree

Subject: [xsl] PART 3 -THE REVERSE DIRECTION -- Yet still moving elements -- to a new location in a different Result-tree
From: "Graves, Jim \(CONTR\)" <jim.graves@xxxxxxx>
Date: Fri, 16 Sep 2005 04:04:34 -0600
ALL: I'm having fun trying to do the reverse of my former problem, (last
week's: 'Moving elements to a new location in the Result-tree') which I
solved, thanks to your help. (I have two very different file formats to
interconvert among. Hence the 'forward' and 'reverse' directions. This
time I'm going back the other way, full circle -- back to the original
source format.)

However, now my templates won't execute, as I want them to -- and I show
what my setup looks like below: [INPUT, OUTPUT, XSLT code], with
comments indicating where the breakdown appears to be.
Using a similar method 'should work' but there is a problem...

I basically want to create a new result tree that contains the ALIASES
in the position immediately following the FORMAL_NAME; instead they wind
up appearing in the input in accordance with the linear order of where
they were in the input stream (where they had to be for the 'other'
format, actually far down below in the linear ordering of elements, at
the bottom).

I tried to apply the same logic that worked (thanks) when going 'the
other way' but apparently I'm missing something or doing something
wrong.

I put the intervening data element, the BIRTH_DATE in between to show
the problem -- the 'real data' has about 10+ other data elements though,
we can ignore them. If these other elements are not present in the input
data, everything works just fine -- but if they are there, then the
template ('ALIAS') does not execute.

Can you spot what the errors could be and help me out? (XSLT newbie)

Clue: this line:  <xsl:apply-templates select="ALIAS" />

isn't executing, as expected, in XMLSpy, version 2005, release 3, Ent.
Edn.
(I marked it up in the code below.)


Thanks in advance, I appreciate it a lot. Jim


INPUT DATA LOOKS LIKE:

<?xml version="1.0" encoding="UTF-8"?>

<Person>

  <NAME_FIRST>First1</NAME_FIRST>
  <NAME_LAST>LastName2</NAME_LAST>
  <NAME_MIDDLE>MiddleName3</NAME_MIDDLE>
  <NAME_PREFIX>Mr.</NAME_PREFIX>
  <BIRTH_DATE>19590506</BIRTH_DATE>
  <GENDER>M</GENDER>
  <IND_HEIGHT>61" - 63"</IND_HEIGHT>
  <IND_WEIGHT>225 - 240 lbs</IND_WEIGHT>
  <HAIR_COLOR>Bald</HAIR_COLOR>
  <EYE_COLOR>Gray</EYE_COLOR>

  <ALIAS>
  <ALIAS_TYPE>UNKNOWN</ALIAS_TYPE>
  <AliasName>ALIAS1, BILL1, JR1</AliasName>
  </ALIAS>

  <ALIAS>
  <ALIAS_TYPE>UNKNOWN</ALIAS_TYPE>
  <AliasName>ALIAS2, BILL2, JR2</AliasName>
  </ALIAS>

  <ALIAS>
  <ALIAS_TYPE>UNKNOWN</ALIAS_TYPE>
  <AliasName>ALIAS3, BILL3, JR3</AliasName>
  </ALIAS>

</Person>

(END OF INPUT)


(START OF OUTPUT -- two versions, first, what I get; second, what I
want.)

I get this:

<?xml version="1.0" encoding="UTF-8"?>
<Transmittal

xmlns:nisteft="http://www.aware.com/formats/nisteft";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; >

	<Person>
		<abc:field name="FORMAL_NAME" number="1">
			<abc:subfield>
				<abc:item>LastName2, First1
MiddleName3</abc:item>
			</abc:subfield>
		</abc:field>


		<abc:field name="THE_ALIAS" number="2"/>
		<!--The ALIASES should be here -->

		<abc:field name="BIRTH_DATE" number="3">
			<abc:subfield>
				<abc:item>19590506</abc:item>
			</abc:subfield>
		</abc:field>


<!--The ALIASES end up here (the wrong place), presumably since the
template ('ALIAS') isn't called-->

		<abc:subfield>
		    <abc:item>ALIAS1, BILL1, JR1</abc:item>
		</abc:subfield>

		<abc:subfield>
			<abc:item>ALIAS2, BILL2, JR2</abc:item>
		</abc:subfield>

		<abc:subfield>
			<abc:item>ALIAS3, BILL3, SR3</abc:item>
		</abc:subfield>

	</Person>
</Transmittal>

(END OF ACTUAL OUTPUT)


(I want this:)


(START OF DESIRED OUTPUT)

<?xml version="1.0" encoding="UTF-8"?>
<Transmittal

xmlns:nisteft="http://www.aware.com/formats/nisteft";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; >

	<Person>

		<abc:field name="FORMAL_NAME" number="1">
			<abc:subfield>
				<abc:item>LastName2, First1
MiddleName3</abc:item>
			</abc:subfield>
		</abc:field>


		<abc:field name="THE_ALIAS" number="2" >

<!-- /////////// THE ALIASES NEED TO BE HERE ////////////////// -->
		    <abc:subfield>
		        <abc:item>ALIAS1, BILL1, JR1</abc:item>
		    </abc:subfield>

		    <abc:subfield>
			    <abc:item>ALIAS2, BILL2, JR2</abc:item>
		    </abc:subfield>

		    <abc:subfield>
			    <abc:item>ALIAS3, BILL3, SR3</abc:item>
		    </abc:subfield>

<!-- /////////////////////////////////////////////// -->
		</abc:field>


		<abc:field name="BIRTH_DATE" number="3">
			<abc:subfield>
				<abc:item>19590506</abc:item>
			</abc:subfield>
		</abc:field>

	</Person>
</Transmittal>

(END OF DESIRED OUTPUT)


HERE IS THE XSLT (erroneous)

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:nisteft="http://www.aware.com/formats/nisteft";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>

<xsl:output version="1.0" method="xml" omit-xml-declaration="no"
encoding="UTF-8" indent="yes"/>

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

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


<xsl:template match="@*|node()">
<!-- Minor question:
Is there a better way to do this than using 'local' variables?-->
        <xsl:variable name="IND_NAME">
		<xsl:value-of select="name()"/>
        </xsl:variable>

        <xsl:variable name="CURRENT_NODE">
		<xsl:value-of select="node()"/>
        </xsl:variable>


    <xsl:choose>

    <xsl:when test="$IND_NAME='NAME_MIDDLE'">
	    <abc:field name="THE_ALIAS" number="2">


************************************************************************
***
<!-- PROBLEM IS HERE: the processor doesn't seem to want to execute
this-->
		<xsl:apply-templates select="ALIAS" />
I want it to put the Alias list here, so it ends up where it belongs in
the copy! What should be here to make it happen?
************************************************************************
**

	    </abc:field>
    </xsl:when>


    <xsl:when test="$IND_NAME='NAME_PREFIX'">
        <xsl:apply-templates select="ALIAS" />
    </xsl:when>

<xsl:when test="$IND_NAME='NAME_FIRST'">
<!-- this part works to reconstruct the name -->
    <xsl:variable name="NL">
				    <xsl:value-of
select="../NAME_LAST"/>
    </xsl:variable>
    <xsl:variable name="NF">
				    <xsl:value-of select="node()"/>
    </xsl:variable>
    <xsl:variable name="NM">
			    <xsl:value-of select="../NAME_MIDDLE"/>
    </xsl:variable>

  <abc:field name="FORMAL_NAME" number="1">
  <!-- this part works to reconstruct the name -->
    <abc:subfield>
      <abc:item>
        <xsl:value-of select="$NL"/>
        <xsl:text>, </xsl:text>
        <xsl:value-of select="$NF"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="$NM"/>
      </abc:item>
    </abc:subfield>
  </abc:field>

<!-- 'calling' the template failed to work as hoped -- is a test needed?
 <abc:field name="THE_ALIAS" number="2" >
      <xsl:call-template name="ALIAS_NAME" />
    </abc:field>
-->


<!-- 'applying' this template failed to work as hoped -- is a test
needed?
 <abc:field name="THE_ALIAS" number="2" >
      <xsl:apply-templates select="ALIAS" />
    </abc:field>
-->

<!-- this part works to add the Birthdate -- but it interferes with the
flow -->
</xsl:when>
	<xsl:when test="$IND_NAME='BIRTH_DATE'">
		<xsl:element name="abc:field">
			<xsl:attribute name="name"><xsl:value-of
select="'BIRTH_DATE'"/></xsl:attribute>
			<xsl:attribute name="number"><xsl:value-of
select="3"/></xsl:attribute>
				<xsl:element name="abc:subfield">
					<xsl:element name="abc:item">
						<xsl:value-of
select="$CURRENT_NODE"/>
					</xsl:element>
				</xsl:element>
	    </xsl:element>
	</xsl:when>
  </xsl:choose>
</xsl:template>


<!--
This is the template I think should do the job -- but the processor
does:
[ <xsl:template match="@*|node()"> ] instead.
-->

<xsl:template match="ALIAS" >
 <abc:subfield>
   <abc:item>
        <xsl:value-of select="AliasName"/>
   </abc:item>
  </abc:subfield>
</xsl:template>



<!-- when using the direct 'call' method (also not called)
<xsl:template name="ALIAS_NAME">
  <abc:subfield>
      <abc:item>
        <xsl:value-of select="AliasName"/>
   </abc:item>
 </abc:subfield>
</xsl:template>
-->

</xsl:stylesheet>

Current Thread