OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

 


 

   Re: [xml-dev] Combining 2 XML into 1 XML via XSLT

[ Lists Home | Date Index | Thread Index ]

I've got it working.  Below is what I have.  The only issue is with the 
second Vehicle node where I'm getting the rows from xml1 the for-each loop 
is getting the rows from xml2 instead of xml1.  Looking into why its doing 
that now.

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; 
version="1.0">
<xsl:output method="xml"/>
<xsl:template match="/">
		<xsl:apply-templates select="vehicle" />
</xsl:template>
<xsl:template match="vehicle">
<xsl:variable name="xml2" select="document('xml2.xml')" />
<vehicles>
	<vehicle aic_id="{@ais_id}">
		<make>
			<xsl:apply-templates select="make" mode="copy" />
		</make>
		<year>
			<xsl:apply-templates select="year" mode="copy" />
		</year>
		<model>
			<xsl:apply-templates select="model" mode="copy" />
		</model>
		<style>
			<xsl:apply-templates select="style" mode="copy" />
		</style>
		<image>
			<xsl:apply-templates select="image" mode="copy" />
		</image>
		<headers>
			<!--get headers from xml1 -->
			<xsl:for-each select="/vehicle/headers/header">
				<!-- set current header -->
				<xsl:variable name="current_header" select="@header_name" />
				<header header_name="{@header_name}">
					<!-- get rows from xml1 for the current header -->
					<xsl:for-each 
select="/vehicle/headers/header[@header_name=($current_header)]/rows/row">
						<xsl:variable name="current_row" select="@row_name"/>
						<row row_name="{@row_name}">
							<xsl:value-of 
select="/vehicle/headers/header[@header_name=($current_header)]/rows/row[@row_name=($current_row)]" 
/>
						</row>
					</xsl:for-each>
					<!--get rows from xml2 that do not exist in xml1 for the current header 
-->
					<xsl:variable name="row_name1">
						<xsl:apply-templates 
select="/vehicle/headers/header[@header_name=($current_header)]/rows/row/@row_name"/>
					</xsl:variable>
					<xsl:for-each 
select="$xml2/vehicle/headers/header[@header_name=($current_header)]/rows/row">
						<xsl:choose>
							<xsl:when test="contains($row_name1, @row_name)"/>
							<xsl:otherwise>
								<row row_name="{@row_name}"/>
							</xsl:otherwise>
						</xsl:choose>
					</xsl:for-each>
				</header>
			</xsl:for-each>
			<!--get headers from xml2 that do not exist in xml1 -->
			<xsl:variable name="header_name1">
				<xsl:apply-templates  select="/vehicle/headers/header/@header_name" 
mode="copy"/>
			</xsl:variable>
			<xsl:for-each select="$xml2//headers/header">
				<xsl:choose>
				      		<xsl:when test="contains($header_name1, @header_name)"/>
				      		<xsl:otherwise>
				      			<xsl:variable name="current_header" select="@header_name" />
				      			<header header_name="{@header_name}"/>
				      		</xsl:otherwise>
					</xsl:choose>
			</xsl:for-each>
		</headers>
	</vehicle>
	<vehicle aic_id="{$xml2//@aic_id}">
		<xsl:copy-of select="$xml2//make" />
		<xsl:copy-of select="$xml2//year" />
		<xsl:copy-of select="$xml2//model" />
		<xsl:copy-of select="$xml2//style" />
		<xsl:copy-of select="$xml2//image" />
		<headers>
			<!--get headers from xml1 -->
			<xsl:for-each select="$xml2/vehicle/headers/header">
				<!-- set current header -->
				<xsl:variable name="current_header1" select="@header_name" />
				<header header_name="{@header_name}">
					<!-- get rows from xml1 for the current header -->
					<xsl:for-each 
select="$xml2/vehicle/headers/header[@header_name=($current_header1)]/rows/row">
						<xsl:variable name="current_row1" select="@row_name"/>
						<row row_name="{@row_name}">
							<xsl:value-of 
select="/vehicle/headers/header[@header_name=($current_header1)]/rows/row[@row_name=($current_row1)]" 
/>
						</row>
					</xsl:for-each>
					<!--get rows from xml2 that do not exist in xml1 for the current header 
-->
					<xsl:variable name="row_name2">
						<xsl:apply-templates 
select="$xml2/vehicle/headers/header[@header_name=($current_header1)]/rows/row/@row_name"/>
					</xsl:variable>
					<xsl:for-each 
select="/vehicle/headers/header[@header_name=('$current_header1')]/rows/row"><!-- 
should be grabbing from xml1 but not -->
						<xsl:choose>
							<xsl:when test="contains($row_name2, @row_name)"/>
							<xsl:otherwise>
								<row row_name="{@row_name}"/>
							</xsl:otherwise>
						</xsl:choose>
					</xsl:for-each>
				</header>
			</xsl:for-each>
			<!--get headers from xml2 that do not exist in xml1 -->
			<xsl:variable name="header_name2">
				<xsl:apply-templates  select="$xml2/vehicle/headers/header/@header_name" 
mode="copy"/>
			</xsl:variable>
			<xsl:for-each select="/vehicle/headers/header">
				<xsl:choose>
				      		<xsl:when test="contains($header_name2, @header_name)"/>
				      		<xsl:otherwise>
				      			<xsl:variable name="current_header" select="@header_name" />
				      			<header header_name="{@header_name}"/>
				      		</xsl:otherwise>
					</xsl:choose>
			</xsl:for-each>
		</headers>
	</vehicle>
</vehicles>
</xsl:template>
</xsl:stylesheet>


----Original Message Follows----
From: Steve Rosenberry <Steve.Rosenberry@ElectronicSolutionsCo.com>
To: xml-dev@lists.xml.org
CC: Dave Yancey <dyancey1@hotmail.com>
Subject: Re: [xml-dev] Combining 2 XML into 1 XML via XSLT
Date: Fri, 13 Sep 2002 08:06:05 -0400



Dave Yancey is looking for a functional equivalent of:

 > <xsl:for-each select="$xml2//headers/header">
 > <xsl:variable name="header_name1"><xsl:value-of
 > select="@header_name"/></xsl:variable>
 > <xsl:for-each select="//headers/header">
 > <xsl:choose>
 > <xsl:when test="@header_name = $header_name1">
 > <xsl:variable name="bFound">true</xsl:variable>
 > </xsl:when>
 > <xsl:when test="@header_name != $header_name1">
 > <xsl:variable name="bFound">false</xsl:variable>
 > </xsl:when>
 > </xsl:choose>
 > </xsl:for-each>
 > <xsl:if test="$bFound='false'">
 > <header>
 > <xsl:attribute name="header_name"><xsl:value-of
 > select="@header_name"/></xsl:attribute>
 > </header>
 > </xsl:if>
 > </xsl:for-each>

Stealing various suggestions from previous responses and taking into
account the inner for-each loop, may I suggest the following:

<xsl:for-each select="$xml2//headers/header">
   <xsl:variable name="header_name1" select="@header_name"/>
   <xsl:if test="count(//headers2/header[@header_name = $header_name1]) =
0">
     <header head_name="{@header_name}"/>
   </xsl:if>
</xsl:for-each>

(FWIW: I didn't see the beginning of this thread so I could be way off
base here...)

--
Steve Rosenberry
Sr. Partner

Electronic Solutions Company -- For the Home of Integration
http://www.ElectronicSolutionsCo.com

(610) 670-1710


----
David Yancey

_________________________________________________________________
MSN Photos is the easiest way to share and print your photos: 
http://photos.msn.com/support/worldwide.aspx





 

News | XML in Industry | Calendar | XML Registry
Marketplace | Resources | MyXML.org | Sponsors | Privacy Statement

Copyright 2001 XML.org. This site is hosted by OASIS