help with html table (nested for-each/keys/matched template)

R

rick

Greetings,

I am trying to generate an html table that looks through the following
xml source and lists links to all of the files (resource-file) and
finds the resource-forms that match those file names and adds the
appropriate file description next to the link to the filename. The xslt
code that I've included doesn't work but gives an idea of what I'm
trying to do. Through my research I believe that using keys and/or
template matching my be the better way to go, but I'm not sure how to
code them. I recognize that the xml structure is a little awkward but
that's what I have to work with. Thanks in advance for any
suggestions.

Rick

XML source

<artifact>
<resource-file>
<artifact>
<displayName>file1.doc</displayName>
<uri>location of file1</uri>
</artifact>
<artifact>
<displayName>file2.doc</displayName>
<uri>location of file2</uri>
</artifact>
</resource-file>
<resource-form>
<file_name>file1.doc</file_name>
<resource_description>file1.doc
description</resource_description>
</resource-form>
<resource-form>
<artifact>
<file_name>file2.doc</file_name>
<resource_description>file1.doc
description</resource_description>
</artifact>
<artifact>
<file_name>file3.doc</file_name>
<resource_description>file3.doc
description</resource_description>
</artifact>
<artifact>
<file_name>file4.doc</file_name>
<resource_description>file4.doc
description</resource_description>
</artifact>
</resource-form>
</artifact>

Desired output

Resource File(s) File Description
(link to file1.doc) file1.doc description
(link to file2.doc) file2.doc description

nonworking xslt code

<table>
<tr>
<td>Resource File(s)</td>
<td>File Description</td>
</tr>
<tr>
<xsl:for-each select="resource-file/artifact">
<xsl:variable name="filename" select="metaData/displayName"/>
<xsl:variable name="filelocation" select="fileArtifact/uri"/>
<xsl:for-each select="resource-form/artifact"['file_name=$filename']>
<tr>
<td>
<a>
<xsl:attribute name="href">
<xsl:value-of select="$filelocation"/>
</xsl:attribute>
<xsl:attribute name="target">blank</xsl:attribute>
<xsl:value-of select="$filename"/>
</a>
</td>
<td>
<b>Resource Description:</b>
<xsl:value-of
select="structuredData/resource-form/resource_description"/>
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
</tr>
</table>
 
?

=?ISO-8859-1?Q?J=FCrgen_Kahrs?=

rick said:
code them. I recognize that the xml structure is a little awkward but
that's what I have to work with. Thanks in advance for any
suggestions.

You dont need XSL for such a trivial data extraction.
The following script in xmlgawk will do all the data
extraction described:

BEGIN { XMLMODE=1 }
XMLCHARDATA { data = $0 }
XMLENDELEM == "displayName" { name = data }
XMLENDELEM == "uri" { uri[name] = data }
XMLENDELEM == "resource_description" { split(data, d); dsc[d[1]] = data }

END {
for (n in uri) {
print uri[n] "\t" n "\t" dsc[n]
}
}

When running the script, you will get the result:

gawk -lxml -f artifact.awk artifact.xml
location of file1 file1.doc file1.doc
description
location of file2 file2.doc file2.doc
description

Notice the line break in the output, which are caused by
your XML data. By the way, there is a bug in your XML data.
 
P

Peter Flynn

rick said:
Greetings,

I am trying to generate an html table that looks through the following
xml source and lists links to all of the files (resource-file) and
finds the resource-forms that match those file names and adds the
appropriate file description next to the link to the filename. The
xslt code that I've included doesn't work but gives an idea of what
I'm trying to do. Through my research I believe that using keys and/or
template matching my be the better way to go,

Definitely. for-each is almost always the wrong answer :)
but I'm not sure how to
code them. I recognize that the xml structure is a little awkward but
that's what I have to work with.

It would be useful -- both to you and your data-supplier -- to meet
with a consultant to discuss improving the efficiency of the XML
through redesigned document markup. The current design is seriously
crippled by the fact that the resource-form element type can apparently
contain either a single file_name/resource_description pair OR multiple
occurrences of the artifact element type, and that the artifact element
type has two apparently mutually exclusive content models, one for
display_name and uri, and one for file_name and resource_description.
Handling inconsistencies like this costs extra time and money, which
you and/or your supplier can save by improving the data model.
Desired output

Resource File(s) File Description
(link to file1.doc) file1.doc description
(link to file2.doc) file2.doc description

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:eek:utput method="html" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="description" match="resource_description"
use="preceding-sibling::file_name"/>

<xsl:template match="/">
<table>
<tr>
<th>Resource File</th>
<th>File Description</th>
</tr>
<xsl:apply-templates
select="artifact/resource-file/artifact/displayName"/>
</table>
</xsl:template>

<xsl:template match="displayName">
<tr>
<td>
<a href="{following-sibling::uri}">
<xsl:apply-templates/>
</a>
</td>
<td>
<xsl:value-of select="key('description',.)"/>
</td>
</tr>
</xsl:template>

</xsl:stylesheet>

This produces:

<table>
<tr>
<th>Resource File</th>
<th>File Description</th>
</tr>
<tr>
<td><a href="location of file1">file1.doc</a></td>
<td>file1.doc description</td>
</tr>
<tr>
<td><a href="location of file2">file2.doc</a></td>
<td>file1.doc description</td>
</tr>
</table>

///Peter
 

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

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top