0

I have the following XML document which I need to convert to a new XML document with extra elements.

    <doc>
        <colleges>           
            <college>           
                <college-name>harvard</college-name>           
                    <members>
                        <!-- College staff-->
                        <staff>    
                            <employee id="2200010001" contract="full-time"/>                             
                            <employee id="2200010002" contract="temp"/>
                        </staff>
                        <!-- College students -->
                        <students>
                            <student id="1000020001"/>
                            <student id="1000020003"/>
                        </students>
                    </members>
            </college>
            <college>           
                <college-name>wharton</college-name>           
                    <members>
                        <!-- College staff-->
                        <staff>    
                            <employee id="2200010003" contract="full-time"/>                             
                            <employee id="2200010004" contract="temp"/>
                        </staff>
                        <!-- College students -->
                        <students>                               
                            <student id="1000020002"/>
                        </students>
                    </members>
                </college>
        </colleges>
        <students>                
            <student id="1000020001">        
                <personal>              
                    <name>
                        <firstname>Hillary</firstname>
                        <lastname>Clinton</lastname>
                    </name>                    
                    <!-- Student contact information -->
                    <contact-information>
                        <phone>+12123004000</phone>
                        <email>[email protected]</email>
                    </contact-information>
                </personal>
                <registration>
                    <!-- Student university information -->                                     
                    <degree>
                        <type>undergrad</type>
                        <status>1</status>
                        <matriculated>yes</matriculated>                    
                    </degree>
                    <degree>
                        <type>masters</type>
                        <status>1</status>
                        <matriculated>yes</matriculated>                    
                    </degree>
                </registration>
            </student">
            <student id="1000020002">
                <personal>              
                    <name>
                        <firstname>Donald</firstname>
                        <lastname>Trump</lastname>
                    </name>
                    <!-- Student contact information -->
                    <contact-information>
                        <phone>+12123004001</phone>
                        <email>[email protected]</email>
                    </contact-information>
                </personal>
                <registration>
                    <!-- Student university information -->                                      
                    <degree>
                        <type>undergrad</type>
                        <status>1</status>
                        <matriculated>yes</matriculated>                    
                    </degree>
                    <degree>
                        <type>masters</type>
                        <status>1</status>
                        <matriculated>yes</matriculated>                    
                    </degree>
                </registration>
            </student">
        </students>
    </doc>

In the student element I need to extract the college name and insert it as element, so student section shows as following: (The remaining part is unchanged, I just added student section for simplicity and readability)

    <student id="1000020001">        
        <personal>              
            <name>
                <firstname>Hillary</firstname>
                <lastname>Clinton</lastname>
            </name>                    
            <!-- Student contact information -->
            <contact-information>
                <phone>+12123004000</phone>
                <email>[email protected]</email>
            </contact-information>
        </personal>
            <registration>
                <!-- Student university information -->  
                <college-name>harvard</college-name>               
                <degree>
                    <type>undergrad</type>
                    <status>1</status>
                    <matriculated>yes</matriculated>                    
                </degree>
                <degree>
                    <type>masters</type>
                    <status>1</status>
                    <matriculated>yes</matriculated>                    
                </degree>
            </registration>
    </student">

I'm using XSLT using Identity rule, but my college-name is empty. Any suggestions?

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <!-- Student registration-->
    <xsl:template match="student/registration">
        <registration>
            <xsl:apply-templates select="@* | *"/>
            <xsl:element name="college-name">
                <xsl:call-template name="extractCollegeName">
                        <xsl:with-param name="student-id" select="student/@id"/>
                </xsl:call-template>
            </xsl:element>
        </registration>
    </xsl:template>

    <!-- check student id for each college -->
    <xsl:template name="extractCollegeName">
        <xsl:param name="student-id"/>
        <xsl:for-each select="/doc/colleges/college">
            <xsl:if test="$student-id = members/students/student/@id">
                <xsl:value-of select="college-name"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>
1

1 Answer 1

1

you can use a key for student IDs such as

<xsl:key name="coll-name" match="college//student" use="@id"/>

from your template student/registration, get the college name by matching the key with the attribute of the parent node student, such as

key('coll-name', ancestor::student/@id)

then get the value of the college-name by using the xpath ancestor::college/college-name

whole stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="coll-name" match="college//student" use="@id"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <!-- Student registration-->
    <xsl:template match="student/registration">
        <registration>
            <xsl:element name="college-name">
                <xsl:value-of select="key('coll-name', ancestor::student/@id)/ancestor::college/college-name"/>
            </xsl:element>
            <xsl:apply-templates select="@* | *"/>
        </registration>
    </xsl:template>

</xsl:stylesheet>

see it working here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.