Can anybody help with an yet another XSLT question?

Soldato
Joined
8 Jan 2003
Posts
3,802
Location
Scotland
My XML file has some HTML tags in it, such as <div>...</div>. In my transform stylesheet, I'd like to be able to replace these. For example, replace the div's with <p>..</p>.

Can someone give me some pointers on how I do this?

Cheers.
 
Can you do something like this?

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

That would put all text content of all div nodes in the document into <p>s.

arty
 
arty said:
Can you do something like this?

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

That would put all text content of all div nodes in the document into <p>s.

arty

won't that put them all in ONE <p> ?

<xsl:for-each select="//div">
<p><xsl:value-of select="text()" /></p>
</xsl:for-each>

should do the trick.

But then again that will go through all the divs in turn and just put then in in p's in the order they are ignoring what's inbetween.
So I would think:

<xsl:template match="div">
<p><xsl:value-of select="text()" /></p>
</xsl:template>

would do it. (not too sure, I'm more used to using XSLT to pull data from one XML file into another format).
 
Ben said:
won't that put them all in ONE <p> ?

<xsl:for-each select="//div">
<p><xsl:value-of select="text()" /></p>
</xsl:for-each>

should do the trick.

But then again that will go through all the divs in turn and just put then in in p's in the order they are ignoring what's inbetween.
So I would think:

<xsl:template match="div">
<p><xsl:value-of select="text()" /></p>
</xsl:template>

would do it. (not too sure, I'm more used to using XSLT to pull data from one XML file into another format).

That would wrap the content in one <p>...</p>. The content actually contains numerous divs, which I basically need to replace. I'll give your suggestion a go.

Cheers.
 
Ben said:
won't that put them all in ONE <p> ?

Yep, sorry :D

Your second suggestion is probably the best, depending on how he wants to do it. Personally I just avoid using any HTML in XML and just generate it all in the XSLT as it avoids any confusion, and allows you to isolate the HTML-producing code etc.

arty
 
So would I but it's not my XML file unfortunately.

I tried to get this working last night but because I tried to nest the template code inside an xsl:if statement, it didn't like that. I'm new to this XSLT lark so I'm still fumbling around in the dark with some things.

For example, say my file.xml contains

Code:
         <xsl:if test="programDuration != ''">
           <p>
             <xsl:copy-of select="programDuration/*" />
           </p>
         </xsl:if>

and the node programDuration contains the following;

<div>HNC - One Year Full-Time</div><div>HND - Two Years Full-Time</div>

How do I code the bit of my transform above to replace the divs in the programDuraiton node with <p> (and </p>) tags? Can I use the apply-template funciton to create another template in my XSLT and then use call-template in my main template to do this?
 
mparter said:
How do I code the bit of my transform above to replace the divs in the programDuraiton node with <p> (and </p>) tags?

Will this work?

Code:
<xsl:apply-templates select="programDuration/div" />

...

<xsl:template match="div">
 <p><xsl:value-of select="text()" /></p>
</xsl:template>

You'll need to make sure you're applying the div template at the right point in the node tree. If you like, post examples of input XML and desired output HTML and I'll try to help you with those as I may not be getting the full picture of the structure of the document you want to transform at the moment :)

arty
 
I don't get any processing errors, but the node in question isn't being output either :(

Here's a sample of the (large) XML file.

Code:
<?xml version="1.0" encoding="UTF-8"?>
<?mso-infoPathSolution PIVersion="1.0.0.0" href="courseprospectus.xsn" name="urn:schemas-microsoft-com:office:infopath:Course-Prospectus:" language="en-us" productVersion="11.0.6565" solutionVersion="1.0.0.76" ?>
<?mso-application progid="InfoPath.Document"?>
<CDM xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2005-06-28T14:08:18" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003">
  <orgUnitRoot>
    <orgUnitName>My Work</orgUnitName>
    <orgUnit>
      <orgUnitID>02</orgUnitID>
      <orgUnitName>Some Place</orgUnitName>
      <orgUnitAcronym></orgUnitAcronym>
      <program language="EN-GB">
        <programID>CODE5.109</programID>
        <programName>Accounting, HNC/D</programName>
        <programCode></programCode>
        <programDescription>
          <!-- REMOVED TEXT -->
        </programDescription>
        <qualification>
          <qualificationName></qualificationName>
          <qualificationDescription></qualificationDescription>
          <profession>
            <!-- REMOVED TEXT -->
          </profession>
          <studyQualification>
            <!-- REMOVED TEXT -->
          </studyQualification>
        </qualification>
        <level>Level 7/8</level>
        <learningObjectives>
          <!-- REMOVED TEXT -->
        </learningObjectives>
        <formalPrerequisites>
          <!-- REMOVED TEXT -->
        </formalPrerequisites>
        <teachingPlace><!-- REMOVED TEXT --></teachingPlace>
        <targetGroup></targetGroup>
        <programDuration>
          <span xmlns="http://www.w3.org/1999/xhtml">
            <div>HNC - One Year Full-Time, Two Years Part-Time. HND - Two Years Full-Time, Four Years Part Time. </div>
          </span>
        </programDuration>
        <expenses></expenses>
      </program>
    </orgUnit>
  </orgUnitRoot>

And here's my current XSLT:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/02/xpath-functions" xmlns:xdt="http://www.w3.org/2005/02/xpath-datatypes" xmlns="http://www.w3.org/1999/xhtml">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>
  <xsl:param name="instituteCode" />
  <xsl:param name="courseCode" />
  <xsl:template match="/">
    <xsl:for-each select="CDM/orgUnitRoot/orgUnit/program[programID = $courseCode]">
      <div id="column1">
        <h2>
          <xsl:value-of select="programName" />
        </h2>
        <p>
          <xsl:copy-of select="programDescription/*" />
        </p>
      </div>
      <div id="column2">
        <xsl:if test="learningObjectives != ''">
          <h3>What You Will Study</h3>
          <xsl:copy-of select="learningObjectives/*" />
        </xsl:if>
        <xsl:if test="formalPrerequisites != ''">
          <h3>Entry Requirements</h3>
          <xsl:copy-of select="formalPrerequisites/*" />
        </xsl:if>
        <xsl:if test="qualification/profession != ''">
          <h3>Career Opportunities</h3>
          <xsl:copy-of select="qualification/profession/*" />
        </xsl:if>
      </div>
       <div id="leftPanel">
         <xsl:if test="(level != '') and (level !='SCQF Level #')">
           <p>
          <strong>
            <xsl:value-of select="level" />
          </strong>
        </p>
         </xsl:if>
         <xsl:if test="programDuration != ''">
           <p>
             <xsl:copy-of select="programDuration/*" />  <!-- THIS IS THE PART CAUSING TROUBLE. THE NODE programDuration's CONTENT CONTAINS DIVs WHICH I WANT TO REPLACE WITH PARAGRAPHS -->
           </p>
         </xsl:if>
         <xsl:if test="teachingPlace != ''">
           <p>
             <strong>Location:</strong>
             <xsl:copy-of select="teachingPlace" />
           </p>
         </xsl:if>
         <p>
           <a href="/student/admissions/application/form.pdf" target="_blank">Download an application form</a>
         </p>
         <p>
           <a href="http://www.adobe.com/products/acrobat/readstep2.html" target="_blank">
             <img alt="Download Adobe Acrobat Reader" src="/assets/images/getacro.gif" />
           </a>
         </p>
       </div>
     </xsl:for-each>
   </xsl:template>
 </xsl:stylesheet>

Thanks for taking the time to look at this.
 
Can you replace the

Code:
<xsl:copy-of select="programDuration/*" />

with

Code:
<xsl:value-of select="programDuration/span/div/text()" />

to fix it? If the content of programDuration is very strict (e.g. there will always be a span containing a div containing plain text) then it should be relatively easy. If not, it might be easier in the long run to post-process it using some sort of regular expression text replaces, I think.

arty
 
Back
Top Bottom