What am I missing on this XSLT transformation? - xslt

I think it might be a silly question, but I read the documentation but it still not working for me.
I have this graphxml (generated my mvn):
<?xml version="1.0" encoding="UTF-8"?> <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<key for="node" id="d0" yfiles.type="nodegraphics"/>
<key for="edge" id="d1" yfiles.type="edgegraphics"/>
<graph id="dependencies" edgedefault="directed">
<node id="966567431"><data key="d0"><y:ShapeNode><y:NodeLabel>myproject.mulesoft.services:utilitymgmt-services:mule:3.0.0-SNAPSHOT</y:NodeLabel></y:ShapeNode></data></node>
<node id="706960270"><data key="d0"><y:ShapeNode><y:NodeLabel>myproject.mulesoft.context:custom-runtime-context:jar:1.0.0-SNAPSHOT:compile</y:NodeLabel></y:ShapeNode></data></node>
<edge source="966567431" target="706960270"><data key="d1"><y:PolyLineEdge><y:EdgeLabel>compile</y:EdgeLabel></y:PolyLineEdge></data></edge>
<node id="1985178707"><data key="d0"><y:ShapeNode><y:NodeLabel>myproject.mulesoft.library:common-error-library:jar:2.0.0-SNAPSHOT:compile</y:NodeLabel></y:ShapeNode></data></node>
<node id="953191605"><data key="d0"><y:ShapeNode><y:NodeLabel>myproject.mulesoft.notification:utility-common-domains:jar:3.0.0-SNAPSHOT:compile</y:NodeLabel></y:ShapeNode></data></node>
<edge source="1985178707" target="953191605"><data key="d1"><y:PolyLineEdge><y:EdgeLabel>compile</y:EdgeLabel></y:PolyLineEdge></data></edge>
<edge source="966567431" target="1985178707"><data key="d1"><y:PolyLineEdge><y:EdgeLabel>compile</y:EdgeLabel></y:PolyLineEdge></data></edge>
</graph></graphml>
And all I'm trying to do at this point is to generate a HTML that shows a table with the dependencies like:
Dependencies
myproject.mulesoft.services:utilitymgmt-services:mule:3.0.0-SNAPSHOT
myproject.mulesoft.context:custom-runtime-context:jar:1.0.0-SNAPSHOT:compile
compile
myproject.mulesoft.library:common-error-library:jar:2.0.0-SNAPSHOT:compile
myproject.mulesoft.notification:utility-common-domains:jar:3.0.0-SNAPSHOT:compile
compile
compile
So this is the xsl I have:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Dependency</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Items</th>
</tr>
<xsl:for-each select="*">
<tr>
<td><xsl:value-of select="/"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
And I was expecting to have each item of the list into a separate TR TD.
But instead it's all into the same TR TD.
Items
com.quadreal.mulesoft.services:qr-identitymgmt-services:mule:3.0.0-SNAPSHOT com.quadreal.mulesoft.context:quadreal-runtime-context:jar:1.0.0-SNAPSHOT:compile compile com.quadreal.mulesoft.library:qr-common-error-library:jar:2.0.0-SNAPSHOT:compile com.quadreal.mulesoft.notification:quadreal-utility-common-domains:jar:3.0.0-SNAPSHOT:compile compile compile
Also even if I remove the for-each tag and keep only the
It still displaying the whole thing instead displaying only the first element.
Also tried to add a template for graph and for-each the elemtns, but then I don't even get the html. I get only the whole text for the dependencies.
Am I missing something or there is something with the graphml that is not properly generated?
I'm adding here the expected HTML code:
<html>
<body>
<h2>Dependency</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Items</th>
</tr>
<tr>
<td>myproject.mulesoft.services:utilitymgmt-services:mule:3.0.0-SNAPSHOT
</td>
</tr>
<tr>
<td>myproject.mulesoft.context:custom-runtime-context:jar:1.0.0-SNAPSHOT:compile
</td>
</tr>
<tr>
<td>compile</td>
</tr>
<tr>
<td>myproject.mulesoft.library:common-error-library:jar:2.0.0-SNAPSHOT:compile
</td>
</tr>
<tr>
<td>myproject.mulesoft.notification:utility-common-domains:jar:3.0.0-SNAPSHOT:compile
</td>
</tr>
<tr>
<td>compile</td>
</tr>
<tr>
<td>compile</td>
</tr>
</table>
</body>
</html>

You are getting only one table row, because you do:
<xsl:for-each select="*">
from the context of the / root node, established by:
<xsl:template match="/">
The / root node has only one child, and that is the graphml root element.
Perhaps you wanted to do:
<xsl:for-each select="*/*/*">
to create a row for every node and/or edge?
Note also that:
<xsl:value-of select="/"/>
makes no sense. It will return the entire text of the entire document. If you'll change it to:
<xsl:value-of select="."/>
you will get the expected result - at least in the given example.

Related

xsl:for-each inside xsl:for-each in table rows and columns

I've just started learning XML/XSL and I've hit a roadblock in one of my assignments. Tried Googling and searching over here but I can't seem to find a question that has a solution that is basic. so what I am trying is to display rows of bucket-type and room-types associated with it. can somebody please help
<list-inventory list-count="2">
<list list-type="Standard" list-order = "1" count-Types = "3">
<types type="BEN2D"></room>
<types type="BESH2D"></room>
<types type="HNK"></room>
</list>
<list list-type="Deluxe" list-order = "2" count-Types = "3">
<types type="SNK"></room>
<types type="TESTKD"></room>
<types type="TESTKD"></room>
</list>
<list-inventory>
I want table as below
Standard | Deluxe
BEN2D |SNK
BESH2D |TESTKD
HNK |TESTKD
I tried below xsl code but i see all list-type in single column and only 1st is being printing for all list-type:
<xsl:for-each select="/contents/list-inventory/list">
<tr>
<td class="alt-th" style="border:1px solid black">
<xsl:value-of select="#list-type"/>
</td>
</tr>
<tr>
<td style="border:1px solid black">
<xsl:for-each select="/contents/list-inventory/list/types">
<span><xsl:value-of select="#type"/></span>
<xsl:if test="position()!=last()">
<br/>
</xsl:if>
</xsl:for-each>
</td>
</tr>
</xsl:for-each>
Can someone help me with xsl:for-each inside a xsl:for-each
It's too bad you did not post your expected result as code. I would assume that you want a separate row for each pair of values. As I stated in the comments, this is far from being trivial.
However, you could make it simpler if you are willing to settle for a single data row, where each cell contains all the values of the corresponding list (your attempt seems to suggest that this is what you actually tried to accomplish).
So, given a well-formed XML input:
XML
<list-inventory list-count="2">
<list list-type="Standard" list-order = "1" count-Types = "3">
<types type="BEN2D"/>
<types type="BESH2D"/>
<types type="HNK"/>
</list>
<list list-type="Deluxe" list-order = "2" count-Types = "3">
<types type="SNK"/>
<types type="TESTKD"/>
<types type="TESTKD"/>
</list>
</list-inventory>
you could do simply:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/list-inventory">
<table border="1">
<!-- header -->
<tr>
<xsl:for-each select="list">
<th>
<xsl:value-of select="#list-type"/>
</th>
</xsl:for-each>
</tr>
<!-- body -->
<tr>
<xsl:for-each select="list">
<td>
<xsl:for-each select="types">
<xsl:value-of select="#type"/>
<br/>
</xsl:for-each>
</td>
</xsl:for-each>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
to get:
Result
<?xml version="1.0" encoding="UTF-8"?>
<table border="1">
<tr>
<th>Standard</th>
<th>Deluxe</th>
</tr>
<tr>
<td>BEN2D<br/>BESH2D<br/>HNK<br/>
</td>
<td>SNK<br/>TESTKD<br/>TESTKD<br/>
</td>
</tr>
</table>
which would render as:
I'm not sure how general you want your solution to be (i.e what inputs does it have to handle other than the example shown), but I would do something like:
<xsl:template match="list-inventory">
<xsl:variable name="list2" select="list[2]/types"/>
<xsl:for-each select="list[1]/types">
<xsl:variable name="position" select="position()"/>
<tr>
<td><xsl:value-of select="#type"/></td>
<td><xsl:value-of select="$list2[$position]/#type"/></td>
</tr>
</xsl:for-each>
</xsl:template>
Both the variables here are needed to avoid problems with context: the effect of an XPath expression depends on the context at the time it is evaluated, so you can evaluate a variable to capture information at the time you're in the right context.

Transforming XLIFF to HTML table with XLST 1.0: group elements with same ID from different parent elements, side by side?

I'm trying to get my head around putting XLIFF's segmented source/target language elements side by side in an HTML table, like
<trans-unit id="/html[1]/head[1]/title[1]" resname="Title">
<source xml:lang="de-DE">E-Mail: Vorlagen</source>
<seg-source>
<mrk mid="1" mtype="seg">E-Mail: Vorlagen</mrk>
<mrk mid="2" mtype="seg">Vorlagen</mrk>
</seg-source>
<target state="translated">
<mrk mid="1" mtype="seg">Email:</mrk>
<mrk mid="2" mtype="seg">Templates</mrk>
</target>
</trans-unit>
should become
<tr>
<td class="mid">1</td> <td class="src">E-Mail:</td> <td class="tgt">Email:<td/>
</tr>
<tr>
<td class="mid">2</td> <td class="src">Vorlagen</td> <td class="tgt">Templates<td/>
</tr>
XLIFF translation units can have any number of sub-segments, it thus must be a solution that, I don't know, counts how many MIDs there are in a TU and then jumps back and forth between the source-segment and target elements (with an incremental counter?) to put them side by side in the table?
I have seen XSLT 2.0 solutions working with "for-each-group" wizardry, but did not yet get an idea of how to do it in XSLT 1.0 (edit: with Xalan 1.11). Frankly, I'm a bit amazed that no one has whipped up a style sheet to show bilingual translations in XLIFF side by side as HTML table, so I thought I'd give it a try. Unfortunately, my XSLT hasn't been used in, like, years and I'm a bit rusty. Any pointers what keyword/topic/web source I should have a look at, if not a straight solution?
Thanks a lot,
Christopher
P.S.: If I can work out a solution, I'll, of course, put it freely online for my fellow translator colleagues (or anyone who wants to get a look at what actually is these XLIFF files they send out to us translators).
Somehow along the following lines:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="tr" match="trans-unit/target/mrk" use="concat(../../#id, '|', #mid)"/>
<xsl:output method="html" indent="yes" version="5" doctype-system="about:legacy-doctype"/>
<xsl:template match="trans-unit[#id]">
<table>
<xsl:apply-templates select="source"/>
<thead>
<tr>
<th>mid</th>
<th>source</th>
<th>target</th>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="seg-source/mrk"/>
</tbody>
</table>
</xsl:template>
<xsl:template match="trans-unit/source">
<caption>
<xsl:apply-templates/>
</caption>
</xsl:template>
<xsl:template match="seg-source/mrk">
<tr>
<td class="mid">
<xsl:value-of select="#mid"/>
</td>
<td class="src">
<xsl:apply-templates/>
</td>
<td class="tgt">
<xsl:apply-templates select="key('tr', concat(../../#id, '|', #mid))/text()"/>
</td>
</tr>
</xsl:template>
<xsl:template match="/">
<html>
<head>
<title>Example</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Improved XSL script with a linked in XML file and applying templates

Here is some XSL script:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msa="http://www.publictalksoftware.co.uk/msa">
<xsl:output method="html" indent="yes" version="4.01"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
doctype-public="//W3C//DTD XHTML 1.0 Transitional//EN"/>
<xsl:variable name="DutyHistory" select="document('DutyAssignHistory.XML')"/>
<xsl:template match="/">
<html>
<head>
<title>Test</title>
</head>
<body>
<xsl:for-each select="MeetingWorkBook/Meeting">
<p>
<xsl:value-of select ="Date/#ThisWeek"/>
</p>
<xsl:variable name="Week" select="Date/#ThisWeek"/>
<table>
<tr>
<td>Sound</td>
<td>
<xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[#Week=$Week and #Mode='Weekend']/msa:Assignment[#Index='1' and #IndexType='Fixed']"/>
</td>
</tr>
<tr>
<td>Platform</td>
<td>
<xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[#Week=$Week and #Mode='Weekend']/msa:Assignment[#Index='5' and #IndexType='Fixed']"/>
</td>
</tr>
<tr>
<td>Left Mike</td>
<td>
<xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[#Week=$Week and #Mode='Weekend']/msa:Assignment[#Index='7' and #IndexType='Fixed']"/>
</td>
</tr>
<tr>
<td>Right Mike</td>
<td>
<xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[#Week=$Week and #Mode='Weekend']/msa:Assignment[#Index='8' and #IndexType='Fixed']"/>
</td>
</tr>
<tr>
<td>Public Talk Chairman</td>
<td>
<xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[#Week=$Week and #Mode='Weekend']/msa:Assignment[#Index='4' and #IndexType='Custom']"/>
</td>
</tr>
<tr>
<td>Watchtower Reader</td>
<td>
<xsl:value-of select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments/msa:DutyAssignmentEntry[#Week=$Week and #Mode='Weekend']/msa:Assignment[#Index='5' and #IndexType='Custom']"/>
</td>
</tr>
</table>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
As you can see it is linking in another XML document for reference. Here is one example of that linked in file:
<?xml version="1.0" encoding="utf-8"?>
<DutyAssignmentHistory xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.publictalksoftware.co.uk/msa">
<DutyAssignments>
<DutyAssignmentEntry Date="2018-01-04" Week="W20180101" Template="0" Mode="Midweek">
<Assignment Index="2" IndexType="Fixed">Name 1</Assignment>
<Assignment Index="5" IndexType="Fixed">Name 2</Assignment>
<Assignment Index="7" IndexType="Fixed">Name 3</Assignment>
<Assignment Index="8" IndexType="Fixed">Name 4</Assignment>
<Assignment Index="13" IndexType="Fixed">Name 5</Assignment>
<Assignment Index="14" IndexType="Fixed">Name 6</Assignment>
</DutyAssignmentEntry>
</DutyAssignments>
</DutyAssignmentHistory>
Potentially a user might want to reference the information in the XML and display it however they like but I am wanting to show them the simplest method.
As you can see there are several criteria:
Week (WYYYYMMDD)
Mode (Midweek, Weekend or Weekly)
Template(0 or higher)
The above will filter to the right week of assignments. Then, to identify the actual assignment:
Index (numeric value)
IndexType (Fixed, CustomFixed or Custom)
Can I use templates in any way (perhaps with variables) to simplify the code as it is getting repetative?
You could use a template and pass parameters, or in XSLT 2.0 or higher you could also define a function, which makes it much easier to use and saves some typing. But for what you are currently doing, a variable and some predicate filters seems to be the most simple and easy.
The most simple and easy way would be to bind a variable with the weekend assignments, and then apply your predicate filter to select the one with the #Index and #IndexType:
<xsl:variable name="Week" select="Date/#ThisWeek"/>
<xsl:variable name="weekend-assignments"
select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments
/msa:DutyAssignmentEntry[#Week=$Week and #Mode='Weekend']/msa:Assignment"/>
<table>
<tr>
<td>Sound</td>
<td>
<xsl:value-of select="$weekend-assignments[#Index='1' and #IndexType='Fixed']"/>
</td>
</tr>
If you make the variable hold an unfiltered set of Assignment elements, you could perform all of the filtering in the predicates:
<xsl:variable name="Week" select="Date/#ThisWeek"/>
<xsl:variable name="assignments"
select="$DutyHistory/msa:DutyAssignmentHistory/msa:DutyAssignments
/msa:DutyAssignmentEntry/msa:Assignment"/>
<table>
<tr>
<td>Sound</td>
<td>
<xsl:value-of
select="$assignments[#Index='1' and #IndexType='Fixed']
[..[#Week=$Week and #Mode='Weekend' and #Template='0']]"/>
</td>
</tr>
If you want to consolidate the logic for generating the columns, you could define a template for msa:Assignment:
<xsl:template match="msa:Assignment">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
And then use it like this:
<table>
<tr>
<td>Sound</td>
<xsl:apply-templates select="$weekend-assignments[#Index='1' and #IndexType='Fixed']"/>
If you want to consolidate the logic for generating rows, you could define a template for msa:Assignment and send in a parameter for the first column:
<xsl:template match="msa:Assignment">
<xsl:param name="label"/>
<tr>
<td><xsl:value-of select="$label"/></td>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:template>
And then use it like this:
<table>
<xsl:apply-templates select="$weekend-assignments[#Index='1' and #IndexType='Fixed']">
<xsl:with-param name="label" select="'Sound'"/>
</xsl:apply-templates>

XSLT: my transform add an unselected element. What am I missing?

Ok, I'm working through some simple tutorials from here:
http://www.cch.kcl.ac.uk/legacy/teaching/7aavdh06/xslt/html/module_06.html
The first exercise involves creating a transformation that produces a certain output. Unfortunately, although I'm close, I get an unwanted element at the start. i.e.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xhtml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />
<xsl:template match="/div/placeName">
<html>
<head />
<body>
<Table>
<tr>
<td>Place Name</td>
<td>
<xsl:value-of select="name" />
</td>
</tr>
<tr>
<td>Place Name (regularised)</td>
<td>
<xsl:value-of select="#reg" />
</td>
</tr>
<tr>
<td>National Grid Reference</td>
<td>
<xsl:value-of select="#key" />
</td>
</tr>
<tr>
<td>Type of building/monument</td>
<td>
<xsl:value-of select="settlement/#type" />
</td>
</tr>
</Table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
but the output I'm getting is:
Location
Place Name Old Warden
Place Name (regularised) Old Warden, St Leonard
National Grid Reference TL 137 443
Type of building/monument Parish church
The rest is fine but the 'Location' is unwanted. The source XML is at the link above. Any idea how I stop the unwanted text appearing? Or, better still, tell me where I'm going wrong! :)
Edit: Here is the output
<?xml version="1.0" encoding="utf-8" ?>
Location
<!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<body>
<table>
<tr>
<td>Place Name</td>
<td>Old Warden</td>
</tr>
<tr>
<td>Place Name (regularised)</td>
<td>Old Warden, St Leonard</td>
</tr>
<tr>
<td>National Grid Reference</td>
<td>TL 137 443</td>
</tr>
<tr>
<td>Type of building/monument</td>
<td>Parish church</td>
</tr>
</table>
</body>
</html>
As Stivel mentions, the "Location" text does come from the head element in your XML.
<div type="location">
<head n="I">Location</head>
<placeName reg="Old Warden, St Leonard" key="TL 137 443">
The reason it is appearing is because of XSTL's built-in templates which it uses when you do not specify a match for an element it is looking for in your XSLT.
You can read up on built-in templates at the W3C page but in short, if XSLT can't find a match it will either continue processing the element's children (without copying the element), or in the case of text or attributes, output the value.
XSLT will start by looking for a match for the document element first, and if you have not provided a template, it will continue looking for a template for the root element, and then its children, and so on.
In your case, you have not provided a template to match anything until /div/placeName, this means XSLT will use the built-in template for the div element. This has two children; head and placeName. You have a template it can use for placeName, but not head and so the built-in template ends up outputing the text for head because you have not told it anything otherwise.
The solution is to simply to add a template to ignore the head element
<xsl:template match="/div/head" />
Here is the full XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xhtml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" indent="yes" />
<xsl:template match="/div/head" />
<xsl:template match="/div/placeName">
<html>
<head />
<body>
<Table>
<tr>
<td>Place Name</td>
<td>
<xsl:value-of select="name" />
</td>
</tr>
<tr>
<td>Place Name (regularised)</td>
<td>
<xsl:value-of select="#reg" />
</td>
</tr>
<tr>
<td>National Grid Reference</td>
<td>
<xsl:value-of select="#key" />
</td>
</tr>
<tr>
<td>Type of building/monument</td>
<td>
<xsl:value-of select="settlement/#type" />
</td>
</tr>
</Table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
When you use this, this should give the output you need.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xhtml" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:template match="div">
<xsl:apply-templates select="placeName"/>
</xsl:template>
<xsl:template match="placeName">
<html>
<head />
<body>
<Table>
<tr>
<td>Place Name</td>
<td>
<xsl:value-of select="name" />
</td>
</tr>
<tr>
<td>Place Name (regularised)</td>
<td>
<xsl:value-of select="#reg" />
</td>
</tr>
<tr>
<td>National Grid Reference</td>
<td>
<xsl:value-of select="#key" />
</td>
</tr>
<tr>
<td>Type of building/monument</td>
<td>
<xsl:value-of select="settlement/#type" />
</td>
</tr>
</Table>
</body>
</html>
</xsl:template>
Probably your <head/> may refer
<head n="I">Location</head>
remove <head/> in xsl and check that.

How to access a root attribute from a deeper level in XSLT

I'm calling a template:
<table>
<xsl:apply-templates select="data/pics/row"/>
</table>
The template is
<xsl:template match="row">
<tr>
<xsl:for-each select="td">
<td border="0">
<a href="{#referencddePage}">
<img src="{pic/#src}" width="{pic/#width}" height="{pic/#height}"/>
</a>
</td>
</xsl:for-each>
</tr>
</xsl:template>
My XML is:
<?xml version="1.0" encoding="iso-8859-8"?>
<?xml-stylesheet type="text/xsl" href="xslFiles\smallPageBuilder.xsl"?>
<data pageNo="3" referencePage="xxxxxxxxxxxxxxx.xml">
<pics>
<row no="0">
<td col="0">
<pic src="A.jpg" width="150" height="120"></pic>
</td>
</row>
</pics>
</data>
I want the line :a h r e f="{#referencddePage}" to get the input from
the root, :a h r e f= "{#referencddePage}"..., but I'm already in the <td level>.
I want the line :a h r e
f="{#referencddePage}" to get the
input from the root :a h r e f=
"{#referencddePage}"... but I'm
already in the <td level>
In case it is a rule that the #referencePage attribute is always an attribute of the top element, then it can always be accessed as:
/*/#referencePage
Therefore, in your code you'll have:
<a href="{/*/#referencePage}">
I would recommend not to use <xsl:for-each> and to use only and`. In this way the resulting XSLT code is more understandable and can be more easily modified in the future:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="row">
<tr>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="td">
<td border="0">
<a href="{/*/#referencePage}">
<xsl:apply-templates/>
</a>
</td>
</xsl:template>
<xsl:template match="pic">
<img src="{#src}" width="{#width}" height="{#height}"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document,
<data pageNo="3" referencePage="xxxxxxxxxxxxxxx.xml">
<pics>
<row no="0">
<td col="0">
<pic src="A.jpg" width="150" height="120"></pic>
</td>
</row>
</pics>
</data>
the wanted output is produced:
<tr>
<td border="0">
<a href="xxxxxxxxxxxxxxx.xml">
<img src="A.jpg" width="150" height="120"/>
</a>
</td>
</tr>
See how each template is so very simple. Also, the code is further simplified.
Now, instead of:
<img src="{pic/#src}" width="{pic/#width}" height="{pic/#height}"/>
we have only:
<img src="{#src}" width="{#width}" height="{#height}"/>
Use an XPATH that "jumps" to the top of the document with a leading slash, then walk down the tree:
/data/#referencePage
Applying it to your stylesheet:
<xsl:template match="row">
<tr>
<xsl:for-each select="td">
<td border="0">
<a href="{/data/#referencePage}">
<img src="{pic/#src}" width="{pic/#width}" height="{pic/#height}"/>
</a>
</td>
</xsl:for-each>
</tr>
</xsl:template>