Satya
Satya

Reputation: 1421

Merge of xml using XSLT matching the values

report.xml

<time-entry>    
<date type="date">2011-02-28</date>    
<description>Learn Ajax,Webservices,JSON in Javascript</description>    
<hours type="float">8.0</hours>    
<id type="integer">35458966</id>    
<person-id type="integer">1111111</person-id>    
<project-id type="integer">1802011</project-id>    
<todo-item-id type="integer">83658683</todo-item-id>  </time-entry>  

<time-entry>    
<date type="date">2011-02-28</date>    
<description>for testing purposes... Ranjeet</description>    
<hours type="float">1.25</hours>    
<id type="integer">35380151</id>    
<person-id type="integer">2222222</person-id>    
<project-id type="integer">1802011</project-id>    
<todo-item-id type="integer" nil="true"></todo-item-id>  </time-entry>

person.xml

<people>

<person>
<person-id type="integer">1111111</person-id> 
<name>xxxx</name>  
</person>

<person>
<person-id type="integer">3333333</person-id> 
<name>aaaaaa</name> 
</person>

<person>
<person-id type="integer">4444444</person-id> 
<name>bbbbbb</name> 
</person>

<person>
<person-id type="integer">2222222</person-id> 
<name>yyyyyy</name>   
</person>
</people>

desired.xml

<time-entry>    
    <date type="date">2011-02-28</date>    
    <description>Learn Ajax,Webservices,JSON in Javascript</description>    
    <hours type="float">8.0</hours>    
    <id type="integer">35458966</id>    
    **<person-id type="integer">1111111</person-id>**  
    **<name>xxxx</name>**  
    <project-id type="integer">1802011</project-id>    
    <todo-item-id type="integer">83658683</todo-item-id>  
</time-entry> 

<time-entry>    
    <date type="date">2011-02-28</date>    
    <description>for testing purposes... Ranjeet</description>    
    <hours type="float">1.25</hours>    
    <id type="integer">35380151</id>    
    **<person-id type="integer">2222222</person-id>**  
    **<name>yyyyyy</name>**    
    <project-id type="integer">1802011</project-id>    
    <todo-item-id type="integer" nil="true"></todo-item-id>  
</time-entry>

Here you can see in the desired.xml one element is added from the person.xml matching the in the both xml.

Kindly reply the xsl to get the desired xml.

Thanks in advance.

Upvotes: 1

Views: 274

Answers (2)

Zack
Zack

Reputation: 1231

Another solution:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="peopleXml" select="document('path\to\people.xml')"/>

<xsl:template match="/">
    <report>
        <xsl:for-each select="//time-entry">
            <time-entry>
                <xsl:for-each select="*">
                    <xsl:choose>
                        <xsl:when test="local-name(.) = 'person-id'">
                            <xsl:copy-of select="."/>
                            <xsl:variable name="personid" select="."/>
                            <name><xsl:value-of select="$peopleXml//person[person-id=$personid]/name"/></name>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:copy-of select="."/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each>
            </time-entry>
        </xsl:for-each>
    </report>
</xsl:template>

</xsl:stylesheet>

Upvotes: 0

Martin Honnen
Martin Honnen

Reputation: 167716

Here is a snippet of XSLT 1.0 that should help:

<xsl:key name="p-by-id" match="people/person" use="person-id"/>

<xsl:variable name="pdoc" select="document('person.xml')"/>

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

<xsl:template match="time-entry/person-id">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
  <xsl:variable name="id" select="."/>
  <xsl:for-each select="$pdoc">
    <xsl:apply-templates select="key('p-by-id', $id)/name"/>
  </xsl:for-each>
</xsl:template>

Upvotes: 2

Related Questions