Hi all,

I've just started to learn XSLT, so apologies if this question is very basic! I want to create a new html document, one of my elements in the XML file uses mixed elements. I want to do more complicated formatting using linked documents etc. but for the moment I am just trying to put one element in italics which is contained in an other element. I suspect I am be doing something wrong with how I am traversing the document or with the context. I will use dummy code here because the document is part of a proposal that I am working on.

Thanks in advance for any help, I have a feeling I may be something really silly!

.....

 <abstract ref="A.2">
            <transcription>
                <p>Some text in here.. blah blah blah blah </p>
                <p>Some more text here <t value="author">an authors name</t> even more text blah blah    blah</p>
                <p>even more text </p>
            </transcription>
            
 </abstract>
<?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"
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" version="2.0">
    
    <xsl:output encoding="UTF-8" method="html"/>
    
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>
     
     <!-- these are other elements which exist in the original xml document -->
    <xsl:template match="//scene"/>
    <xsl:template match="//title">
        <h1>Title: <xsl:value-of select="."/></h1>
        <h2>The following text is an abstract only.</h2>
        
    </xsl:template>
    
    <!-- t is the element which i what to italicize which is contained within p -->
    <!--<xsl:template match="//t">
        <i><xsl:value-of select="."/></i>
     </xsl:template>-->
    
    
    <xsl:template match="//p">
        <p><xsl:value-of select="."/></p>       
    </xsl:template>   

</xsl:stylesheet>

Recommended Answers

All 5 Replies

I'd be happy to help, but I don't understand what you want you want to produce.

Your basic idea is correct. You're matching on any "t" node and italicizing it's value. That's the correct temple rule per say. The question is how do you want to APPLY the template and what you want the output nodeset to look like.

If you provide a mockup output html document, I'll write something to show you how to get it there.

I'd be happy to help, but I don't understand what you want you want to produce.

Your basic idea is correct. You're matching on any "t" node and italicizing it's value. That's the correct temple rule per say. The question is how do you want to APPLY the template and what you want the output nodeset to look like.

If you provide a mockup output html document, I'll write something to show you how to get it there.

Hi, thanks for the help.

I want my output document to produce a basic html file that looks like the following:

<html>
     <.....>
     <body>
              <h1>Title: Title of abstract</h1>
               <h2>The following is an abstract only.</h2>
               <p>Some text in here.. blah blah blah blah </p>
               <p>Some more text here <i>an authors name</i> even more text blah blah           
                blah</p>
                <p>even more text </p>
     </body>

The problem is I either output <p> with no italics or I can italicise the authors name but lose the <p> formatting. The test xml and html code will have more t nodes to italicise through out the text.

Thanks again for the help, I appreciate your time.

You've got the right idea with your code. The problem with mixed elements nodes, and the processing of children element nodes within, is that you really have text nodes inside as well that you have to deal with. For example if you look at the line

<p>Second Line: First Text node here. <i>an authors name</i> Second Line: Second Text Node here</p>

What you really have is an element node 'p'. With 3 children. The first text node, the t element node, and the second text node that comes after. When you go to process this particular 'p' element node, you have to process the first text node, then the t element node, then the last text node.

So the following input document was used. (I marked your up a bit)

<abstract ref="A.2">
    <title>Some Book Title</title>
    <transcription>
        <p>First Line of Text: Some text in here.. blah blah blah blah</p>
        <p>Second Line: First Text node here. <t value="author">an authors name</t> Second Line: Second Text Node here</p>
        <p>Third Line of Text</p>
    </transcription>
</abstract>

This transformation will produce the below output.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" version="2.0">

    <xsl:output encoding="UTF-8" method="html"/>

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

    <xsl:template match="abstract">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="title">
        <h1>Title:
            <xsl:value-of select="."/>
        </h1>
        <h2>The following text is an abstract only.</h2>
    </xsl:template>

    <xsl:template match="transcription">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="p">
        <xsl:copy>
            <xsl:value-of select="."/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="p[t]">
        <p>
            <xsl:apply-templates select="t/preceding-sibling::text()" />
            <xsl:apply-templates select="t" />
            <xsl:apply-templates select="t/following-sibling::text()" />
        </p>
    </xsl:template>

    <xsl:template match="t">
        <i>
            <xsl:value-of select="."/>
        </i>
    </xsl:template>

    <xsl:template match="scence"/>
</xsl:stylesheet>

Output HTML

<html xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
    <body>
        <h1>Title:
            Some Book Title</h1>
        <h2>The following text is an abstract only.</h2>
        <p>First Line of Text: Some text in here.. blah blah blah blah</p>
        <p>Second Line: First Text node here. <i>an authors name</i> Second Line: Second Text Node here</p>
        <p>Third Line of Text</p>
    </body>
</html>

Notice in the template that matches p[t], I'm processing the first text node, then the 't' node, the the following text node. This provides the output that you desire.

Hi , thanks a lot for that, thats a great help and you explained it extremely well. Thanks again.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.