469,306 Members | 2,504 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,306 developers. It's quick & easy.

XSLT beginner's question

I have 5 days of experince with XSLT and I am sure my problem is
pretty much as basic as they come but I cannot work it out, so I hope
someone will take pity on me - please!

I have inherited an XML file format which has one header node and
several child nodes :

<wi workitemid= "99999" .... etc .... />
<widata dataname="AMOUNT" datadisplay="Amount" datavalue="123.45"/>
<widata dataname="ADDRESS1" datadisplay="Address" datavalue="Line
1" >
<widata .... etc ....

and am processing them using XSLT to produce an HTML table, by for
example :

<xsl:apply-templates select="widata[@dataname = 'AGENTNAME']"
mode="left_left"/>

The template puts the value of datadisplay into one table cell, and
the value of datavalue into the next cell.

So far, so good. However, how would I get the values from two widata
nodes and concatenate them so that I can put them into one cell? I
know about the concat function but I am having problems getting hold
of the values from the nodes and storing them so that I can then use
that function.

I hope I have included enough info to be helpful.

Thank-you.

Martin
Jul 20 '05 #1
13 18437
Use variables to hold the values and then concat the variables.

<td>

<xsl:variable name="state">
<xsl:value-of select="widata[@dataname = 'ADDRESS3']/@datavalue" />
<!-- or some other node selection -->
</xsl:variable>

<xsl:variable name="zip">
<xsl:value-of select="widata[@dataname = 'ADDRESS4']/@datavalue" />
<!-- or some other node selection -->
</xsl:variable>

....

<xsl:value-of select="concat($state, ' ', $zip)" />

....

</td>

HTH,
-vin

Martin wrote:
I have 5 days of experince with XSLT and I am sure my problem is
pretty much as basic as they come but I cannot work it out, so I hope
someone will take pity on me - please!

I have inherited an XML file format which has one header node and
several child nodes :

<wi workitemid= "99999" .... etc .... />
<widata dataname="AMOUNT" datadisplay="Amount" datavalue="123.45"/>
<widata dataname="ADDRESS1" datadisplay="Address" datavalue="Line
1" >
<widata .... etc ....

and am processing them using XSLT to produce an HTML table, by for
example :

<xsl:apply-templates select="widata[@dataname = 'AGENTNAME']"
mode="left_left"/>

The template puts the value of datadisplay into one table cell, and
the value of datavalue into the next cell.

So far, so good. However, how would I get the values from two widata
nodes and concatenate them so that I can put them into one cell? I
know about the concat function but I am having problems getting hold
of the values from the nodes and storing them so that I can then use
that function.

I hope I have included enough info to be helpful.

Thank-you.

Martin


Jul 20 '05 #2
On 5 Sep 2003 10:00:57 -0700, co*****@hotmail.com (Martin) wrote:
However, how would I get the values from two widata
nodes and concatenate them so that I can put them into one cell?
With concat(), or by using two <xsl:value-of /> elements next to each
other.
I am having problems getting hold
of the values from the nodes and storing them so that I can then use
that function.


So don't store them. Write two XPath expressions, get them working
and tested separately, then cut-and-paste each one into the arguments
to concat()

Jul 20 '05 #3
Thank you both for your responses. They both make sense to me but I'm
still doing something not quite right because I can't get either of
them to transform.

Firstly my XPath expressions are fine now, thanks for the pointers.
I've put them in a couple of xsl:comments and the values are what I'm
after. However,

Vin - if I use your suggestion, I get the error

A reference to variable or parameter 'x' cannot be resolved. The
variable or parameter may not be defined, or it may not be in scope.

This has completely puzzled me as the only time at the moment I
reference the variable is when I try to allocate a value to it; I
haven't got to the point of trying to then use that value later on, so
how can it possibly be that when I create the variable and at the same
time allocate a value to it the variable is out of scope ?!

Andy - I have tried pasting my XPath expressions as you suggested :

<xsl:call-template name="left_left">
<xsl:with-param name="data" select="concat(
xsl:value-of select='widata[@dataname =
&quot;AGENTID&quot;]/@datavalue' ,
' ' ,
xsl:value-of select='widata[@dataname =
&quot;AGENTNAME&quot;]/@datavalue')"
/>
</xsl:call-template>

I get the error

Keyword xsl:call-template may not contain PCDATA nodes.

Please could you help me understand these issues.

Thanks,

Martin
Jul 20 '05 #4
In article <ac**************************@posting.google.com >,
Martin <co*****@hotmail.com> wrote:

% <xsl:call-template name="left_left">
% <xsl:with-param name="data" select="concat(
% xsl:value-of select='widata[@dataname =
% &quot;AGENTID&quot;]/@datavalue' ,
% ' ' ,
% xsl:value-of select='widata[@dataname =
% &quot;AGENTNAME&quot;]/@datavalue')"
% />

You're trying to put xslt elements inside an xpath expression. Try

% <xsl:call-template name="left_left">
% <xsl:with-param name="data" select="concat(
widata[@dataname ='AGENTID']/@datavalue,
% ' ' ,
widata[@dataname = 'AGENTNAME']/@datavalue)"
% />
% </xsl:call-template>

The suggestion to concatenate two xsl:value-of was simply to do that:

<xsl:template name="left_left">
<!-- whatever -->
<xsl:value-of select ="widata[@dataname ='AGENTID']/@datavalue"/>
<xsl:value-of select ="widata[@dataname = 'AGENTNAME']/@datavalue"/>
<!-- whatever else -->
</xsl:template>
--

Patrick TJ McPhee
East York Canada
pt**@interlog.com
Jul 20 '05 #5
pt**@interlog.com (Patrick TJ McPhee) wrote in message news:<bj**********@news.eusc.inter.net>...
You're trying to put xslt elements inside an xpath expression. Try

% <xsl:call-template name="left_left">
% <xsl:with-param name="data" select="concat(
widata[@dataname ='AGENTID']/@datavalue,
% ' ' ,
widata[@dataname = 'AGENTNAME']/@datavalue)"
% />
% </xsl:call-template>


Thank you, Patrick. Yes, I was trying to make it more complicated
than was necessary. I have now got it working and I appreciate the
help that you and everyone else gave me.

I would still like to understand the problem I had earlier when trying
to use a variable. I have stripped down my stlyesheet to the
following minimum skeleton :

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:output method="html"/>
<xsl:template match="/">
<html>
<body>
<xsl:variable name="agentname" select="0"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
I still get the error : "A reference to variable or parameter
'agentname' cannot be resolved. The variable or parameter may not be
defined, or it may not be in scope".

Can anyone enlighten me as to what I am doing wrong here, please?

Martin
Jul 20 '05 #6
In article <ac*************************@posting.google.com> ,
Martin <co*****@hotmail.com> wrote:

% to use a variable. I have stripped down my stlyesheet to the
% following minimum skeleton :
%
% <xsl:stylesheet version="1.0"
% xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
% xmlns:fo="http://www.w3.org/1999/XSL/Format">
%
% <xsl:output method="html"/>
% <xsl:template match="/">
% <html>
% <body>
% <xsl:variable name="agentname" select="0"/>
% </body>
% </html>
% </xsl:template>
% </xsl:stylesheet>

% I still get the error : "A reference to variable or parameter
% 'agentname' cannot be resolved. The variable or parameter may not be
% defined, or it may not be in scope".

Are you sure this is the stylesheet giving that error? There is no
reference to agentname here. Is there another stylesheet with
$agentname in it somewhere?

--

Patrick TJ McPhee
East York Canada
pt**@interlog.com
Jul 20 '05 #7
Martin wrote:

I would still like to understand the problem I had earlier when trying
to use a variable. I have stripped down my stlyesheet to the
following minimum skeleton :

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:output method="html"/>
<xsl:template match="/">
<html>
<body>
<xsl:variable name="agentname" select="0"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
I still get the error : "A reference to variable or parameter
'agentname' cannot be resolved. The variable or parameter may not be
defined, or it may not be in scope".

Can anyone enlighten me as to what I am doing wrong here, please?


Are you using *-PARAM agentname* as a command-line option?

Jul 20 '05 #8
vin sharma <vi********@hp.com> wrote in message news:<1Q*****************@news.cpqcorp.net>...
Are you using *-PARAM agentname* as a command-line option?


No, I am using XSLDebugger (http://www.vbxml.com/xsldebugger/)to do my
development, and it is this that is giving me the error message.

Should my previously posted stylesheet work OK? If so, then maybe
this product is buggy?? Is there another freeware product or
alternative method I can use instead?

Can I throw in another issue that I've come up against? Now that my
concat statement is working I want to add line breaks between my
values and so I am trying to get <BR> tags in my output HTML.

<xsl:call-template name="left_left">
<xsl:with-param name="data" select="concat(
widata[@dataname = 'ADDRESS1']/@datavalue, '&#x3c;' 'BR',
'&#x3e;',
widata[@dataname = 'ADDRESS2']/@datavalue, '&#x3c;' 'BR',
'&#x3e;',
etc.

However, this gets transformed into
&lt;BR&gt;
not
<BR>
and so my HTML doesn't display as I want it.

How can I get the angle brackets to output please?

Martin
Jul 20 '05 #9
You can't output tags as data. Output them as HTML tags.

Bob Foster

"Martin" <co*****@hotmail.com> wrote in message
news:ac**************************@posting.google.c om...
vin sharma <vi********@hp.com> wrote in message news:<1Q*****************@news.cpqcorp.net>...
Are you using *-PARAM agentname* as a command-line option?


No, I am using XSLDebugger (http://www.vbxml.com/xsldebugger/)to do my
development, and it is this that is giving me the error message.

Should my previously posted stylesheet work OK? If so, then maybe
this product is buggy?? Is there another freeware product or
alternative method I can use instead?

Can I throw in another issue that I've come up against? Now that my
concat statement is working I want to add line breaks between my
values and so I am trying to get <BR> tags in my output HTML.

<xsl:call-template name="left_left">
<xsl:with-param name="data" select="concat(
widata[@dataname = 'ADDRESS1']/@datavalue, '&#x3c;' 'BR',
'&#x3e;',
widata[@dataname = 'ADDRESS2']/@datavalue, '&#x3c;' 'BR',
'&#x3e;',
etc.

However, this gets transformed into
&lt;BR&gt;
not
<BR>
and so my HTML doesn't display as I want it.

How can I get the angle brackets to output please?

Martin

Jul 20 '05 #10
"Bob Foster" <bo********@comcast.net> wrote in message news:<Ad_6b.390623$Ho3.58511@sccrnsc03>...
You can't output tags as data. Output them as HTML tags.

Bob Foster


Ah, but how?? I really am very new to this stuff and it is very
different from the VB with which I mainly make my living. I'm trying
to learn from books and the helpful people on here but at the moment
all I can find are the ways I cannot do this! I have tried each of
the following :

<xsl:call-template name="left_left">
<xsl:with-param name="data" select="concat(
widata[@dataname = 'SEC_ADDRESS2']/@datavalue, '&#x3c;', 'BR',
'&#x3e;',
widata[@dataname = 'SEC_ADDRESS3']/@datavalue, <BR>,
widata[@dataname = 'SEC_ADDRESS4']/@datavalue, '<BR>',

with the following results :
the first one transforms into &gt; and &lt; and displays as <BR> as
I've already said;
the second and third ones say that "the character '<' cannot be used
in an attribute value" which I understand and which was why I tried
using the hex values.

It was suggested to me that a captial A with a circumflex (hex C2)
might act as an escape character but it only seems to work with a
pound-sterling sign £, not generally.

So, I am still in the dark as to how to output these tags as I
require. Please can anyone offer further help.

Thanks,

Martin
Jul 20 '05 #11
Martin (co*****@hotmail.com) wrote:
: "Bob Foster" <bo********@comcast.net> wrote in message news:<Ad_6b.390623$Ho3.58511@sccrnsc03>...
: > You can't output tags as data. Output them as HTML tags.
: >
: > Bob Foster
: >

: Ah, but how?? I really am very new to this stuff and it is very
: different from the VB with which I mainly make my living. I'm trying
: to learn from books and the helpful people on here but at the moment
: all I can find are the ways I cannot do this! I have tried each of
: the following :

: <xsl:call-template name="left_left">
: <xsl:with-param name="data" select="concat(
: widata[@dataname = 'SEC_ADDRESS2']/@datavalue, '&#x3c;', 'BR',
: '&#x3e;',
: widata[@dataname = 'SEC_ADDRESS3']/@datavalue, <BR>,
: widata[@dataname = 'SEC_ADDRESS4']/@datavalue, '<BR>',

: with the following results :
: the first one transforms into &gt; and &lt; and displays as <BR> as
: I've already said;
: the second and third ones say that "the character '<' cannot be used
: in an attribute value" which I understand and which was why I tried
: using the hex values.

Butting in, if I missed something, sorry, but...

To get the < into the attribute, the attribute actually has to contain the
literal string &lt; (i.e. four characters). To get that sequence of
characters into the outer "layer" of markup you have to encode those four
characters (which actually means just the & cause it's the thing that's
special).
So I would try &amp;lt;

(or even &amp;amp;lt; , though that might be one level of encoding too
many)
Jul 20 '05 #12
co*****@hotmail.com (Martin) writes:
"Bob Foster" <bo********@comcast.net> wrote in message
news:<Ad_6b.390623$Ho3.58511@sccrnsc03>...
You can't output tags as data. Output them as HTML tags.

Bob Foster


Ah, but how?? I really am very new to this stuff and it is very
different from the VB with which I mainly make my living. I'm
trying to learn from books and the helpful people on here but at the
moment all I can find are the ways I cannot do this! I have tried
each of the following :

<xsl:call-template name="left_left">
<xsl:with-param name="data" select="concat(
widata[@dataname = 'SEC_ADDRESS2']/@datavalue, '&#x3c;', 'BR',
'&#x3e;',
widata[@dataname = 'SEC_ADDRESS3']/@datavalue, <BR>,
widata[@dataname = 'SEC_ADDRESS4']/@datavalue, '<BR>',


Try this:

<xsl:call-template name="left_left">
<xsl:with-param name="data">
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS2']/@datavalue"/>
<br/>
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS3']/@datavalue"/>
<br/>
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS4']/@datavalue"/>
<br/>
</xsl:with-param>
</xsl:call-template>

--
Dean Tiegs, NEĀ¼-20-52-25-W4
ā€œConfortare et esto robustusā€
http://telusplanet.net/public/dctiegs/
Jul 20 '05 #13
In article <ac**************************@posting.google.com >,
Martin <co*****@hotmail.com> wrote:

% "Bob Foster" <bo********@comcast.net> wrote in message
% news:<Ad_6b.390623$Ho3.58511@sccrnsc03>...
% > You can't output tags as data. Output them as HTML tags.
% >
% > Bob Foster
% >
%
% Ah, but how??

Go back to the other suggestion for generating the parameter:

<xsl:call-template name="left_left">
<xsl:with-param name="data">
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS1']/@datavalue"/>
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS2']/@datavalue"/>
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS3']/@datavalue"/>
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS4']/@datavalue"/>
</xsl:with-param>
</xsl:call-template>

Now insert the breaks between them. I think you have to use xsl:element
to do this, since <br> is not well-formed. I expect if you're using
xhtml you could write <br/> directly, but I'm not an html maven.
<xsl:call-template name="left_left">
<xsl:with-param name="data">
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS1']/@datavalue"/>
<xsl:element name="br"/>
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS2']/@datavalue"/>
<xsl:element name="br"/>
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS3']/@datavalue"/>
<xsl:element name="br"/>
<xsl:value-of select="widata[@dataname = 'SEC_ADDRESS4']/@datavalue"/>
<xsl:element name="br"/>
</xsl:with-param>
</xsl:call-template>

Now, in template left_left, you refer to this using copy-of, rather than
value-of

<xsl:copy-of select="$data"/>

copy-of will insert a node tree, while value-of inserts the concatenated
text nodes (i.e., throwing away the <br> nodes).
--

Patrick TJ McPhee
East York Canada
pt**@interlog.com
Jul 20 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by timothy ma and constance lee | last post: by
3 posts views Thread by Chris | last post: by
reply views Thread by inetquestion | last post: by
4 posts views Thread by Adrian von Bidder | last post: by
7 posts views Thread by pstachy | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by suresh191 | last post: by
1 post views Thread by Geralt96 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.