Hi All,
I am not sure where am i going wrong but this is something which made me realise that my understanding about the for-each and apply-templates was wrong. :(

I have 2 XMLs, I want to display the 'value' present in one XML after comparing the 'name' present in both the XML's

1st XML (XML1.xml) from which i'll pick the values-

<?xml version="1.0" encoding="UTF-8"?>
<alpha>
    <table name="tab1">
        <data>
            <prop>
                <name>abc</name>
                <value>123</value>
                <ismultival>0</ismultival>
            </prop>
            <prop>
                <name>xyz</name>
                <value>456</value>
                <ismultival>0</ismultival>
            </prop>
            <prop>
                <name>lmn</name>
                <value>789</value>
                <ismultival>0</ismultival>
            </prop>            
        </data>
        <data>
            <prop>
                <name>zyx</name>
                <value>987</value>
                <ismultival>0</ismultival>
            </prop>
            <prop>
                <name>nml</name>
                <value>654</value>
                <ismultival>2</ismultival>
            </prop>
            <prop>
                <name>cba</name>
                <value>321</value>
                <ismultival>0</ismultival>
            </prop>            
        </data>
    </table>
    <table name="tab2">
        <data>
            <prop>
                <name>asd</name>
                <value>147</value>
                <ismultival>2</ismultival>
            </prop>
            <prop>
                <name>qwe</name>
                <value>852</value>
                <ismultival>0</ismultival>
            </prop>
            <prop>
                <name>zxc</name>
                <value>369</value>
                <ismultival>1</ismultival>
            </prop>            
        </data>
    </table>    
</alpha>

2nd XML (XML2.xml), from which i'll pick the name and will compare with the 1st one-

<props>
    <prop>
        <name>abc</name>
    </prop>
    <prop>
        <name>xyz</name>
    </prop>
    <prop>
        <name>lmn</name>
    </prop>
</props>

the required Output XML-

<output>
    <prop>
        <name>abc</name>
        <value>123</value>
    </prop>
    <prop>
        <name>zyx</name>
        <value>987</value>
    </prop>
    <prop>
        <name>zxc</name>
        <value>369</value>
        <subprop>
            <name>asd</name>
            <value>147</value>
        </subprop>
    </prop>    
</output>

In this XML if you'll see the subprop is the prop with 'multivalue' set as 2 within the same 'data', however, through my XSL i am not able to get the 'subprop' nodes.

the XSL I tried-

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>	
    
    <xsl:param name="namevalxml" select="XML1.xml"/>
    <xsl:param name="nameonlyxml" select="XML2.xml"/>
    
    <xsl:template match="/">
        <output>
            <prop>
                <xsl:apply-templates select="$namevalxml/alpha/table/data"/>
            </prop>
        </output>        
    </xsl:template>
    <xsl:template match="data">
        <xsl:apply-templates select="prop"/>
    </xsl:template>
    
    <xsl:template match="prop">
        <xsl:variable name="propname">
            <xsl:value-of select="./name"/>
        </xsl:variable>
        <xsl:variable name="propval">
            <xsl:value-of select="./value"/>
        </xsl:variable>
        <xsl:if test="./ismultival!=2">            
            <xsl:for-each select="$nameonlyxml/props/prop">
                <xsl:if test="./name=$propname">
                    <name><xsl:value-of select="$propname"/></name>
                    <value><xsl:value-of select="$propval"/></value>
                </xsl:if>
            </xsl:for-each>            
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

This is just a sample xml and xsl's, i am looking for the logic to do this. So any suggestion or help is most welcome.. :)

xml for testing

<?xml version="1.0" encoding="UTF-8"?>
<alpha>
    <table name="tab1">
        <data>
            <prop>
                <name>abc</name>
                <value>123</value>
                <ismultival>0</ismultival>
            </prop>
            <prop>
                <name>xyz</name>
                <value>456</value>
                <ismultival>0</ismultival>
            </prop>
            <prop>
                <name>lmn</name>
                <value>789</value>
                <ismultival>0</ismultival>
            </prop>            
        </data>
        <data>
            <prop>
                <name>xyz</name>
                <value>987</value>
                <ismultival>0</ismultival>
            </prop>
            <prop>
                <name>nml</name>
                <value>654</value>
                <ismultival>2</ismultival>
            </prop>
            <prop>
                <name>cba</name>
                <value>321</value>
                <ismultival>0</ismultival>
            </prop>            
        </data>
    </table>
    <table name="tab2">
        <data>
            <prop>
                <name>asd</name>
                <value>147</value>
                <ismultival>2</ismultival>
            </prop>
            <prop>
                <name>qwe</name>
                <value>852</value>
                <ismultival>0</ismultival>
            </prop>
            <prop>
                <name>zxc</name>
                <value>369</value>
                <ismultival>1</ismultival>
            </prop>            
        </data>
    </table>    
</alpha>

props.xml

<?xml version="1.0"?>
<props>
    <prop>
        <name>abc</name>
    </prop>
    <prop>
        <name>xyz</name>
    </prop>
    <prop>
        <name>lmn</name>
    </prop>
</props>
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output indent="yes" method="xml"/>
	<xsl:variable name="search" select="document('props.xml')//name"/>
	<xsl:template match="/">
		<output>
			<data>
				<xsl:variable name="cn" select="count($search)"/>
				<xsl:value-of select="$cn"/>
				<xsl:for-each select="$search">
					<xsl:choose>
						<xsl:when test="position() = $cn">
							<xsl:value-of select="concat(position(),' ',.)"/>
						</xsl:when>
						<xsl:otherwise>
							<xsl:value-of select="concat(position(),' ',.,',')"/>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:for-each>
			</data>
			<xsl:apply-templates select="alpha"/>
		</output>
	</xsl:template>
	<xsl:template match="alpha">
		<xsl:apply-templates select="table[@name='tab1']" mode="tab1"/>
	</xsl:template>
	<xsl:template match="table" mode="tab1">
		<xsl:apply-templates select="data"/>
	</xsl:template>
	<xsl:template match="data">
		<xsl:apply-templates select="prop"/>
	</xsl:template>
	<xsl:template match="prop">
		<xsl:variable name="found" select="."/>
		<xsl:for-each select="$search">
			<xsl:if test="$found/name = .">
				<prop>
					<name>
						<xsl:value-of select="$found/name"/>
					</name>
					<vaule>
						<xsl:value-of select="$found/value"/>
					</vaule>
				</prop>
			</xsl:if>
		</xsl:for-each>
	</xsl:template>
</xsl:stylesheet>

result

<?xml version='1.0' encoding='UTF-8' ?>
<output>
  <data>31 abc,2 xyz,3 lmn</data>
  <prop>
    <name>abc</name>
    <vaule>123</vaule>
  </prop>
  <prop>
    <name>xyz</name>
    <vaule>456</vaule>
  </prop>
  <prop>
    <name>lmn</name>
    <vaule>789</vaule>
  </prop>
  <prop>
    <name>xyz</name>
    <vaule>987</vaule>
  </prop>
</output>

or it may be that and xml2 xml1
and the desired results fit together

can not produce the desired results-I
I do not why the mistake with the time-value-xyz 987 appears

I changed original xml

Edited 5 Years Ago by xml_looser: n/a

This article has been dead for over six months. Start a new discussion instead.