RE: merging unknown nodes

Subject: RE: merging unknown nodes
From: "Oleg Shpak" <oshpak@xxxxxxxxxxxxxxxxxx>
Date: Thu, 2 Nov 2000 17:19:22 -0400 (EST)
Hello Jon,

yes, it is possible.

Use the stylesheet below.
It is assumed that OPTIONLIST/@name is unique within a single PRODUCT.

How it works.
First, it selects all OPTIONLIST nodes.
Iterating through them it checks whether an OPTIONLIST node with this
@name is the first occurrence in the document

not(../preceding-sibling::PRODUCT/OPTIONLIST[@name=current()/@name])

{exactly: tests for first occurrence of PRODUCT node, which contains
	OPTIONLIST node with @name equal to current node's @name.
	If you allow several OPTIONLIST nodes with the same @name
	within a single PRODUCT add
	  not(preceding-sibling::OPTIONLIST[@name=current()/@name])
	i.e.
   	  not(preceding-sibling::OPTIONLIST[@name=current()/@name]) and
     not(../preceding-sibling::PRODUCT/OPTIONLIST[@name=current()/@name])
}

If it is the first occurrence then it processes all OPTIONLIST nodes
with current @name throughout the document.

Iteration is done without sorting, so document order of nodes is retained.
But even if you sort, the condition will evaluate to true only once for
every
distinct @name value.

It does not check whether a particular option is already included into
generated
OPTIONLIST, but I think you can add this yourself using the same approach.

I don't insist that this is a good approach, but it works.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:template match="/">
    <OPTIONS>
      <xsl:for-each select="PRODUCTS/PRODUCT/OPTIONLIST">
        <xsl:if
test="not(../preceding-sibling::PRODUCT/OPTIONLIST[@name=current()/@name])">
          <OPTIONLIST name="{@name}">
            <xsl:for-each
select="../../PRODUCT/OPTIONLIST[@name=current()/@name]/OPTION">
              <xsl:copy-of select="."/>
            </xsl:for-each>
          </OPTIONLIST>
        </xsl:if>
      </xsl:for-each>
    </OPTIONS>
  </xsl:template>
</xsl:stylesheet>

it generates the following XML from yours:
<?xml version="1.0" encoding="UTF-8"?>
<OPTIONS>
	<OPTIONLIST name="fred">
		<OPTION>fred1</OPTION>
		<OPTION>fred2</OPTION>
		<OPTION>fred3</OPTION>
		<OPTION>fred4</OPTION>
	</OPTIONLIST>
	<OPTIONLIST name="george">
		<OPTION>george1</OPTION>
		<OPTION>george2</OPTION>
	</OPTIONLIST>
</OPTIONS>

Tested with Xalan 1.0.0.

Regards,
	Oleg.

Date: Wed, 1 Nov 2000 10:02:51 -0400 (EST)
From: "Jon Payne" <Jon.Payne@xxxxxxxxxx>
Subject: merging unknown nodes

I'm new to XSL(T) and so far I have not been able to think of a way of
achieving the required transform using XSLT and I think I'm going to have to
result to using some JavaScript or may be some plain old C code :-(

What I want to be able to do is transform this:

<PRODUCTS>
    <PRODUCT name="bill_product">
        <OPTIONLIST name="fred"> <!-- The first 'fred' option list -->
            <OPTION>fred1</OPTION>
            <OPTION>fred2</OPTION>
        </OPTIONLIST>
        <OPTIONLIST name="george">
            <OPTION>george1</OPTION>
        </OPTIONLIST>
    </PRODUCT>

    <PRODUCT name="bob_product">
        <OPTIONLIST name="fred">   <!-- The second 'fred' optionlist -->
            <OPTION>fred3</OPTION>
            <OPTION>fred4</OPTION>
        </OPTIONLIST>
        <OPTIONLIST name="george">
            <OPTION>george2</OPTION>
        </OPTIONLIST>
    </PRODUCT>
<PRODUCTS>

Into this:

<OPTIONLIST name="fred">	<!-- All the 'fred' optionlist's merged into
one -->
    <OPTION>fred1</OPTION>
    <OPTION>fred2</OPTION>
    <OPTION>fred3</OPTION>
    <OPTION>fred4</OPTION>
</OPTIONLIST>
<OPTIONLIST name="george">	<!-- All the 'george' optionlist's merged into
one -->
    <OPTION>george1</OPTION>
    <OPTION>george2</OPTION>
</OPTIONLIST>

If the transform was literally just this one case then it wouldn't be a
problem however I want to be able to merge all OPTIONLIST's with the same
name into one OPTIONLIST with that name i.e. I don't want to be limited to
just 'fred' and 'george' option lists but I want to have any number of
different named OPTIONLIST's and have them merged.

Is this possible using just XSLT (in which case I guess I just don't have a
good enough understanding yet) or am I going to have to use a procedural
langauge to solve this part?

TIA,

Jon Payne


TTPCom Ltd				Tel: +44 1483 565050
20 Nugent Road
Surrey Research Park
Guildford
Surrey GU2 7DF  UK            http://www.ttpcom.com




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

------------------------------

End of The XSL-List Digest V3 #318
**********************************





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


Current Thread