Using one template to process different nodes?

A

afc46220

Hello,

I am a novice with XSL, and can't quite figure out how to come up with
a solution for the following problem. Let's assume we have the
following set of XML nodes:

<DataBlocks>
<AlphaBlock>
<AlphaBlock.Name>Alpha<AlphaBlock.Name/>
<AlphaBlock.Value>1<Alpha.Block.Value/>
<AlphaBlock/>
<BetaBlock>
<BetaBlock.Name>Beta</BetaBlock.Name/>
<BetaBlock.Value>2<BetaBlock.Block.Value/>
<BetaBlock/>
<DataBlocks/>

Alpha and Beta blocks contain information that can be processed in
identical way, therefore I intend to utilize one template, something
like:

<xsl:template match="DataBlocks//AlphaBlock | DataBlocks//BetaBlock">
....
<xsl:template/>

Within that template, I want to create a variable, which would hold the
name of the node:

<xsl:variable name="BlockType">
<xsl:choose>
<xsl:when test = "contains(current(),
'BetaBlock')>BetaBlock</xsl:when>
<xsl:eek:therwise>AlphaBlock</xsl:eek:therwise>
</xsl:choose>
</xsl:variable>

My goal is then to use that variable to access both AlphaBlock.Value
and BetaBlock.Value nodes in something like:

Value is <xsl:value-of select="concat($BlockType,'.Value')"/>, but
certainly it does not work.

I would appreciate your help.

Thanks.

Alex.
 
R

Richard Tobin

Alpha and Beta blocks contain information that can be processed in
identical way, therefore I intend to utilize one template, something
like:

<xsl:template match="DataBlocks//AlphaBlock | DataBlocks//BetaBlock">
...
<xsl:template/>

Yes, that's reasonable.
Within that template, I want to create a variable, which would hold the
name of the node:

<xsl:variable name="BlockType">
<xsl:choose>
<xsl:when test = "contains(current(),
'BetaBlock')>BetaBlock</xsl:when>
<xsl:eek:therwise>AlphaBlock</xsl:eek:therwise>
</xsl:choose>
</xsl:variable>

You are testing whether the the text content of the element contains the
string "BetaBlock" which doesn't correspond to what you said you wanted.
The simplest way to get the name of the element into the variable is
to do something like

My goal is then to use that variable to access both AlphaBlock.Value
and BetaBlock.Value nodes in something like:

Value is <xsl:value-of select="concat($BlockType,'.Value')"/>, but
certainly it does not work.

You can't dynamically create a pattern to match. But you can do
something like this:

<xsl:value-of select="*[name() = concat($BlockType, '.Value')"/>

That you are having to do this suggests that the design of your
document is not optimal. Why not simply have

<AlphaBlock>
<Name>Alpha</Name>
<Value>1</Value>
<AlphaBlock/>

Or even <Block type="Alpha">

-- Richard
 
A

afc46220

Richard,

Thanks. I will try your suggestion tomorrow.

As for the design of the original XML document, I can't argue - it's
far from being optimized, but it's a legacy document, and its structure
can't be changed at this point.

Alex.
 
R

Richard Tobin

As for the design of the original XML document, I can't argue - it's
far from being optimized, but it's a legacy document, and its structure
can't be changed at this point.

If you're going to have to do a lot of work on these documents, you
might consider writing a stylesheet to first convert it into a more
tractable form, rather than constantly dealing with the original.

-- Richard
 
J

JAPISoft

<xsl:variable name="BlockType" select="local-name(.)"/> is enough

<xsl:value-of select="*[local-name(.)=concat( $BlockType, '.Name' )]"/>

<xsl:value-of select="*[local-name(.)=concat( $BlockType, '.Value' )]"/>

Best regards,

A.Brillant
EditiX - XML Editor and XSLT Debugger
http://www.editix.com
 

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,776
Messages
2,569,603
Members
45,190
Latest member
ClayE7480

Latest Threads

Top