Reputation: 347
I have this Input XML:
<?xml version="1.0" encoding="utf-8"?>
<Document>
<File>
<Id>123</Id>
<Created>21/12/2013</Created>
</File>
<Employee>
<Personal>
<Name>Juan Dela Cruz</Name>
<Age>27</Age>
<Address>
<Street1>Street1</Street1>
<Street2>Street2</Street2>
<PostalCode>123456</PostalCode>
</Address>
</Personal>
<Employment>
<DateHired>21/12/2013</DateHired>
<Position>Clerk</Position>
<EmploymentType>Contractual</EmploymentType>
<Department>Sales</Department>
</Employment>
</Employee>
<Employee>
<Personal>
<Name>Juana Change</Name>
<Age>28</Age>
<Address>
<Street1>Street1</Street1>
<Street2>Street2</Street2>
<PostalCode>123456</PostalCode>
</Address>
</Personal>
<Employment>
<DateHired>22/12/2013</DateHired>
<Position>Manager</Position>
<EmploymentType>Full-Time</EmploymentType>
<Department>Sales</Department>
</Employment>
</Employee>
</Document>
Which I need to transform into something like this:
<Profiles>
<File>
<FileId>123</FileId>
<FileDate>21/12/2013</FileDate>
</File>
<EmployeeProfile>
<Information>
<EmpName>Juan Dela Cruz</EmpName>
<Age>27</Age>
<EmpAddress>Street1 Street2, 123456</EmpAddress>
<EmpStartDate>21/12/2013</EmpStartDate>
<EmpPosition>Clerk</EmpPosition>
<EmpType>Contractual</EmpType>
<EmpDepartment>Sales</EmpDepartment>
</Information>
</EmployeeProfile>
<EmployeeProfile>
<Information>
<EmpName>Juana Change</EmpName>
<Age>28</Age>
<EmpAddress>Street1 Street2, 123456</EmpAddress>
<EmpStartDate>22/12/2013</EmpStartDate>
<EmpPosition>Manager</EmpPosition>
<EmpType>Full-Time</EmpType>
<EmpDepartment>Sales</EmpDepartment>
</Information>
</EmployeeProfile>
</Profiles>
Is there a way for mew to do this using XSLT, because the source XML is from a different format than the format I wanted it to have.
Please let me know and thanks in Advance
Upvotes: 1
Views: 60
Reputation: 86744
Here's a partial stylesheet to get you started:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Document">
<Profiles>
<xsl:apply-templates select="*"/>
</Profiles>
</xsl:template>
<xsl:template match="File">
<File>
<FileId><xsl:value-of select="Id"/></FileId>
<FileDate><xsl:value-of select="Created"/></FileDate>
</File>
</xsl:template>
<xsl:template match="Employee">
<Information>
<EmpName><xsl:value-of select="Personal/Name"/></EmpName>
<Age><xsl:value-of select="Personal/Age"/></Age>
.
.
.
</Information>
</xsl:template>
</xsl:stylesheet>
The key to understanding this is to realize how the XSL processor works. The stylesheet is not a "program" in the traditional sense. It is a set of rules that get applied as the processor reads your XML. It takes some getting used to but when you "get" it the beauty of XSL will become apparent.
Upvotes: 1
Reputation: 116959
How about doing it the simple way:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<Profiles>
<File>
<FileId><xsl:value-of select="Document/File/Id"/></FileId>
<FileDate><xsl:value-of select="Document/File/Created"/></FileDate>
</File>
<xsl:for-each select="Document/Employee">
<EmployeeProfile>
<Information>
<EmpName><xsl:value-of select="Personal/Name"/></EmpName>
<Age><xsl:value-of select="Personal/Age"/></Age>
<EmpAddress>
<xsl:value-of select="Personal/Address/Street1"/>
<xsl:text> </xsl:text>
<xsl:value-of select="Personal/Address/Street2"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="Personal/Address/PostalCode"/>
</EmpAddress>
<EmpStartDate><xsl:value-of select="Employment/DateHired"/></EmpStartDate>
<EmpPosition><xsl:value-of select="Employment/Position"/></EmpPosition>
<EmpType><xsl:value-of select="Employment/EmploymentType"/></EmpType>
<EmpDepartment><xsl:value-of select="Employment/Department"/></EmpDepartment>
</Information>
</EmployeeProfile>
</xsl:for-each>
</Profiles>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 7173
Here is an example of a push-type stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<!-- This is called an identity template -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Document">
<EmployeeProfile>
<xsl:apply-templates/>
</EmployeeProfile>
</xsl:template>
<xsl:template match="File">
<Profile>
<xsl:apply-templates/>
</Profile>
</xsl:template>
<xsl:template match="File/Id">
<ProfileId>
<xsl:apply-templates/>
</ProfileId>
</xsl:template>
<xsl:template match="File/Created">
<ProfileDate>
<xsl:apply-templates/>
</ProfileDate>
</xsl:template>
<xsl:template match="Employee">
<Information>
<xsl:apply-templates/>
</Information>
</xsl:template>
<xsl:template match="Personal|Employment">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="Personal/Name">
<EmpName>
<xsl:apply-templates/>
</EmpName>
</xsl:template>
<xsl:template match="Personal/Address">
<EmpAddress>
<xsl:for-each select="*">
<xsl:value-of select="."/>
<xsl:if test="position()!=last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</EmpAddress>
</xsl:template>
<xsl:template match="Employment/DateHired">
<EmpStartDate>
<xsl:apply-templates/>
</EmpStartDate>
</xsl:template>
<xsl:template match="Employment/Position">
<EmpPosition>
<xsl:apply-templates/>
</EmpPosition>
</xsl:template>
<xsl:template match="Employment/EmploymentType">
<EmpType>
<xsl:apply-templates/>
</EmpType>
</xsl:template>
<xsl:template match="Employment/Department">
<EmpDepartment>
<xsl:apply-templates/>
</EmpDepartment>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0