I am trying to get the ageCode attribute from the xml below and with an xslt, put <Adults>3</Adults> if the ageCode = 10 or <Children>0</Children> if the `ageCode = 8. Here is my sample xml:
<Root>
<Reservations>
<Reservation>
<Rooms>
<Room>
<Guests>
<Guest ageCode="10" count="3" />
<Guest ageCode="8" count="0" />
</Guests>
</Room>
</Rooms>
</Reservation>
</Reservations>
</Root>
I am trying to tranform it into:
<Reservation>
<Rooms>
<Room>
<Adults>3</Adults>
<Children>0</Children>
</Room>
</Rooms>
</Reservation>
with the follwing XSLT, but I can’t get it to work (I am completely new to XSLT):
<?xml version="1.0" encoding="iso-8859-1"?>
<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="/">
<xsl:element name="Reservation">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="Root/Reservations/Reservation/Rooms/Room/Guests">
<xsl:for-each select="Guest">
<xsl:if test="@ageCode = '10'">
<xsl:element name="Adults">
<xsl:value-of select="@count"/>
</xsl:element>
</xsl:if>
<xsl:if test="@ageCode = '8'">
<xsl:element name="Children">
<xsl:value-of select="@count"/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
How does XSLT work? By this I mean does it go from top to bottom applying templates? I ask because you said I needed 3 templates and with each one applied, a new transformation was made.
What does the first and second template actually do? Is there a way you could show the XML after the first is applied, then the second? Am I understanding XSLT correctly here?
What do you mean by applies deeper templates?
Would a tool like MapForce be useful if I have to create many XSLT’s?
You need 3 templates: one to discard the top 2 elements, one to match everything and just output itself and recurse, and one to do your guests -> adults transformation.
The first one is
It outputs nothing and applies deeper templates.
The second is
It outputs itself (that is, an element with the current name) and applies deeper templates.
The third is what you have, but just match “Guests” instead of the full path:
BTW, you don’t need to use
xsl:elementwith a constant name, just use a literal.