Link to home
Start Free TrialLog in
Avatar of Jammerules
Jammerules

asked on

Applying templates using XSLT on a simple XML

I am a noob to XML and XSLT, so pardon me for such a question. Here is what I am trying to do. I have an XML file like this:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xsltfile_ex2.xslt"?>
<Profiles>
    <Profile>
      <Salutation>Mr. </Salutation>  
      <FirstName>Barack</FirstName>
      <LastName>Obama</LastName>
      <ID>123</ID>
    </Profile>
</Profiles>

Open in new window


And I have an XSLT file like this:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
  <xsl:output method="html"/>

  <xsl:template match="/">
    <html>
      <body>
        <xsl:apply-templates select="Profiles/Profile"/>         
      </body>
    </html>
  </xsl:template>

  <xsl:template match="Profile"> 
      <tr>
          <xsl:apply-templates select="./FirstName"/>
      </tr>
  </xsl:template>

  <xsl:template match="FirstName">
    <tr bgcolor="red">
        <xsl:apply-templates select="./LastName"/>        
    </tr>
  </xsl:template>

  <xsl:template match="LastName">
    <tr bgcolor="red">
      <xsl:value-of select="./LastName"/>
    </tr>
  </xsl:template>
</xsl:stylesheet>
 

Open in new window


I am trying to get the Last Name from the XML. What is it that I am doing wrong? If someone also could please explain to me how the control flows in the above example (after correction), I'd appreciate that. Thanks!
ASKER CERTIFIED SOLUTION
Avatar of mccarl
mccarl
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Jammerules
Jammerules

ASKER

Hey McCarl,

I am reading your answer on my phone and pretty much "got" what I wanted and where I am going wrong. I will execute your code once I am home, but I am sure it works!. If I have further questions with this example, I hope you'd answer :) Thanks!!!
No worries, your welcome!
OK - check this code out:

XSLT:
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
  <xsl:output method="html"/>

  <xsl:template match="/">
    <html>
      <body>
        <table bgcolor ="grey" border="1">
          <xsl:apply-templates select="Profiles/Profile"/>
        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="Profile"> 
      <tr>
          <xsl:apply-templates select="./LastName"/>          
      </tr>
  </xsl:template>

  <xsl:template match="LastName">     
          <xsl:value-of select="."/>
          <br/>
          <xsl:apply-templates select="./Occupations/Occupation"/>
  </xsl:template>

  <xsl:template match="Occupation">
    <xsl:value-of select="."/> 
  </xsl:template>
  
</xsl:stylesheet>
 

Open in new window

XML:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="xsltfile_ex2.xslt"?>
<Profiles>
    <Profile>
      <Salutation>Mr. </Salutation>  
      <FirstName>Barack</FirstName>
      <LastName>Obama
          <Occupations>
              <Occupation>USA Prez</Occupation> 
          </Occupations>
      </LastName>
      <ID>123</ID>
    </Profile>
</Profiles>

Open in new window

For some reason, while I just wanted the Last Name on row 1 of the table and Occupation on row 2 of the table, what I am getting is "Last Name AND Occupation" on row 1 and Occupation on row 2. Why?
> Why?

Because (on line 23) you are asking it to output the 'value of' the LastName element, which basically means everything in that element except markup. It doesn't matter that the occupation is within its own element, it is all still within the LastName element so when you ask for value-of select="." you get everything.

How to fix this? (Firstly, I just have to say that it is very strange to have the Occupation as part of the LastName element, I am hoping that you are doing this just for your own learning. If this was an actual XML file that needed processing, I would shoot the person who designed the schema! :)... But to fix this the way the XML currently is is easy. Change line 23 to...

<xsl:value-of select="text()"/>

Open in new window

Here we are specifically asking for the "text" node within the LastName element node and as such we only output "Obama", rather than before where we were asking it to output everything within the LastName element node.
... I would shoot the person who designed the schema!

Bwahaha!! Sorry, that unfortunate person is me that designed the schema. I, honestly, do not know how the Occupation ended up inside of LastName :). I will be more sensible in the future...lol. But, thanks so much for the explanation!

On a side note, I don't know if this is OK to ask, but is there a way I could communicate with you via the forum messenger (if there is such a thing)? That way when I have new questions posted on in here, you could try and answer it. It is a win win for the both of us. If not, I'd understand.
;) Glad to help.

No, there isn't really any way to do that. But if you post further questions in the same topic areas that you did this one, then I have notifications set up so that I get emailed when the new questions come in, so I will see anything that you post.
+1.

Looking forward to having a ton of my 'silly noob' questions to be answered by you!