XSLT help

S

silver_sabrina

Hey everyone, I'm having some trouble with this. I need to convert one
xml doc into another and I think that XSLT may be the answer, so I'd
like some help from the gurus out here :) If XSLT cannot solve the
problem then I think I'll have to write a Java program using DOM or
something.

Here is an example of what I am trying to accomplish - basically, I
need to do a lookup on the author's first name and last name and then
create the nested XML structure containing book info by that author

Source XML:

<books>
<author>
<fname>William</fname>
<lname>Shakespeare</lame>
<bookName>Merchant of Venice</bookName>
<bookRank>One</bookRank>
</author>
<author>
<fname>William</fname>
<lname>Shakespeare</lame>
<bookName>As You Like It</bookName>
<bookRank>Two</bookRank>
</author>
</books>

Needs to be transformed to:

<books>
<author>
<fname>William</fname>
<lname>Shakespeare</lname>
<books>
<book>
<bookName>Merchant of Venice</bookName>
<bookRank>One</bookRank>
</book>
<book>
<bookName>As You Like It</bookName>
<bookRank>Two</bookRank>
</book>
</books>
</author>
</books>

I'm not an expert in XSL so don't know if this is even possible?
Thanks,
Sabrina
 
D

David Carlisle

Hey everyone, I'm having some trouble with this. I need to convert one
xml doc into another and I think that XSLT may be the answer, so I'd
like some help from the gurus out here :) If XSLT cannot solve the
problem then I think I'll have to write a Java program using DOM or
something.

Here is an example of what I am trying to accomplish - basically, I
need to do a lookup on the author's first name and last name and then
create the nested XML structure containing book info by that author

Source XML:

<books>
<author>
<fname>William</fname>
<lname>Shakespeare</lame>
<bookName>Merchant of Venice</bookName>
<bookRank>One</bookRank>
</author>
<author>
<fname>William</fname>
<lname>Shakespeare</lame>
<bookName>As You Like It</bookName>
<bookRank>Two</bookRank>
</author>
</books>

Needs to be transformed to:

<books>
<author>
<fname>William</fname>
<lname>Shakespeare</lname>
<books>
<book>
<bookName>Merchant of Venice</bookName>
<bookRank>One</bookRank>
</book>
<book>
<bookName>As You Like It</bookName>
<bookRank>Two</bookRank>
</book>
</books>
</author>
</books>

I'm not an expert in XSL so don't know if this is even possible?
Thanks,
Sabrina
in xslt2, this does what you need, he xsl1 version would be similar just
replace xsl:for-each-group by the muenchian grouping technique (ask google)

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput indent="yes"/>
<xsl:template match="books">
<books>
<xsl:for-each-group select="author"
group-by="concat(fname,'/',lname)">
<author>
<xsl:copy-of select="fname,lname"/>
<books>
<xsl:for-each select="current-group()">
<book>
<xsl:copy-of select="bookName,bookRank"/>
</book>
</xsl:for-each>
</books>
</author>
</xsl:for-each-group>
</books>
</xsl:template>
</xsl:stylesheet>
 
J

Joe Kesselman

David said:
(e-mail address removed) wrote:
replace xsl:for-each-group by the muenchian grouping technique (ask google)

Or, more directly, see the XSLT FAQ for examples of that approach:
http://www.dpawson.co.uk/xsl/sect2/sect21.html

See the Grouping page, and possibly the Sorting and Grouping page as well.

(If you're working in XSLT, Dave Pawson's collection of tips gathered
from the XSLT Users' mailing list is a *wonderful* resource -- it
summarizes and organizes years of experience in making XSLT do things
ranging from simple to "I thought that was impossible.")
 
S

silver_sabrina

That is just beautiful! I know about the muenchian grouping technique
but I think its such a pain to use. Its great that XSL2.0 has this
feature.

FYI, I'm using SAXON as it supports xsl 2.0.

Sample Java Code:

public static void main(String[] args) throws Exception
{
System.setProperty("javax.xml.transform.TransformerFactory",
"net.sf.saxon.TransformerFactoryImpl");

String xslID = "transform.xsl" ;
String sourceID = "file.xml";

// Create a transform factory instance.
TransformerFactory tfactory =
TransformerFactory.newInstance();
InputStream xslIS =
new BufferedInputStream(new FileInputStream(xslID));
StreamSource xslSource = new StreamSource(xslIS);


// Create a transformer for the stylesheet.
Transformer transformer = tfactory.newTransformer(xslSource);
InputStream xmlIS =
new BufferedInputStream(new FileInputStream(sourceID));
StreamSource xmlSource = new StreamSource(xmlIS);

// Transform the source XML to System.out.
transformer.transform(xmlSource, new
StreamResult(System.out));
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top