473,402 Members | 2,050 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,402 software developers and data experts.

XPath using an element value in XSL

Hi,

I have some XML like this:

<family>
<person name="bob">
<father ref="../../person[2]" />
</person>
<person name="charlie">
<child ref="../../person" />
</person>
</family>

When I template match on person I want to get a handle on the referenced
father element so that I can apply a template to it. Does anyone know if
this is possible and how?

E.g.
<xsl:template match="person">
<xsl:value-of select="@name"/>
<xsl:if test="count(father) != 0">
Father: <xsl:apply-templates select="eval(@ref)">
</xsl:if>
</xsl:template>

Note that the eval() function is what I'm missing.

Many thanks
Pat Turner
Jul 20 '05 #1
4 3421
Note that the eval() function is what I'm missing.


it is provided as an extension function by some systems (eg saxon has a
saxon:evaluate that does this)

the pure XSLT1 way of doing this is a two stage transform, in the first
pass you write out a stylesheet that has the XPath extracted from the
source in a suitable select attribute, then you execute the generated
stylesheet.

David
Jul 20 '05 #2
Thanks David,

errrm, could you give me an example of what the first pass stylesheet
would look like using my example? I can't think how it would be done.

TIA
Pat
David Carlisle wrote:
Note that the eval() function is what I'm missing.

it is provided as an extension function by some systems (eg saxon has a
saxon:evaluate that does this)

the pure XSLT1 way of doing this is a two stage transform, in the first
pass you write out a stylesheet that has the XPath extracted from the
source in a suitable select attribute, then you execute the generated
stylesheet.

David

Jul 20 '05 #3
Pat Turner <pu************@netscape.net> writes:
Thanks David,

errrm, could you give me an example of what the first pass stylesheet
would look like using my example? I can't think how it would be done.

TIA
Pat


several ways, depending how generic/efficient you want to be.

for example

input doc (eval.xml):

<family>
<person name="bob">
<father ref="../../person[2]" />
</person>
<person name="charlie">
<child ref="../../person[1]" />
</person>
</family>
proto-stylesheet (eval1.xsl)
<xsl:stylesheet version="1.0"
xmlns:x="data:,x"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template mode="a" match="person">
<xsl:value-of select="@name"/>
</xsl:template>

<xsl:template match="person">
Person: <xsl:value-of select="@name"/>
<xsl:apply-templates select="father|child"/>
</xsl:template>

<xsl:template x:match="father">
Father: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" x:select="@ref"/>
</xsl:template>

<xsl:template x:match="child">
Child: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" x:select="@ref"/>
</xsl:template>

</xsl:stylesheet>
in the above the syntax (which I just made up) is that templates
depending on a generated xpath use x:match in their match pattern, and
use x:select where they want the xpath to appear. This could be made
more efficient (i generate all templates for all dynamic xpaths which is
less code for me to write but generates more templates than needed)

Evaluation stylesheet (this has original source doc filename hardcoded,
it could be a parameter)

<xsl:stylesheet version="1.0"
xmlns:x="data:,x"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template mode="a" match="person">
<xsl:value-of select="@name"/>
</xsl:template>

<xsl:template match="person">
Person: <xsl:value-of select="@name"/>
<xsl:apply-templates select="father|child"/>
</xsl:template>

<xsl:template x:match="father">
Father: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" x:select="@ref"/>
</xsl:template>

<xsl:template x:match="child">
Child: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" x:select="@ref"/>
</xsl:template>

</xsl:stylesheet>



generate real stylesheet
saxon -o eval2.xsl eval1.xsl eval.xsl

eval2.xsl has several templates expanded out. and looks like

<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:x="data:,x" version="1.0">
<xsl:template mode="a" match="person">
<xsl:value-of select="@name"/>
</xsl:template>

<xsl:template match="person">
Person: <xsl:value-of select="@name"/>
<xsl:apply-templates select="father|child"/>
</xsl:template>
<xsl:template match="father[@ref='../../person[2]']">
Father: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" select="../../person[2]"/>
</xsl:template>
<xsl:template match="father[@ref='../../person[1]']">
Father: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" select="../../person[1]"/>
</xsl:template>
<xsl:template match="child[@ref='../../person[2]']">
Child: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" select="../../person[2]"/>
</xsl:template>
<xsl:template match="child[@ref='../../person[1]']">
Child: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" select="../../person[1]"/>
</xsl:template>

</xsl:stylesheet>

run this stylesheet on original source:

$ saxon eval.xml eval2.xsl
<?xml version="1.0" encoding="utf-8"?>

Person: bob
Father: charlie

Person: charlie
Child: bob

Jul 20 '05 #4
Hi David,

thanks very much for the thorough working example. I see what you have
done. I guess if I wanted a generic way to provide this functionality
I'd have to write a third pass stylesheet. I.e. if I have no way of
knowing which nested elements are references of not.

FYI, I'm actually transforming a serialised graph of Java objects. This
means that elements which use references and elements which don't can
change quite easily when java code is refactored. So a generic, reusable
solution would be more pleasing.

I think it also shows that I'll be much better off using an extension. I
believe Xalan (which I am using) has such an evaluate function.

I appreciate knowing how it can be done nonetheless.

Thanks again,
Pat.

David Carlisle wrote:
Pat Turner <pu************@netscape.net> writes:

Thanks David,

errrm, could you give me an example of what the first pass stylesheet
would look like using my example? I can't think how it would be done.

TIA
Pat

several ways, depending how generic/efficient you want to be.

for example

input doc (eval.xml):

<family>
<person name="bob">
<father ref="../../person[2]" />
</person>
<person name="charlie">
<child ref="../../person[1]" />
</person>
</family>
proto-stylesheet (eval1.xsl)
<xsl:stylesheet version="1.0"
xmlns:x="data:,x"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template mode="a" match="person">
<xsl:value-of select="@name"/>
</xsl:template>

<xsl:template match="person">
Person: <xsl:value-of select="@name"/>
<xsl:apply-templates select="father|child"/>
</xsl:template>

<xsl:template x:match="father">
Father: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" x:select="@ref"/>
</xsl:template>

<xsl:template x:match="child">
Child: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" x:select="@ref"/>
</xsl:template>

</xsl:stylesheet>
in the above the syntax (which I just made up) is that templates
depending on a generated xpath use x:match in their match pattern, and
use x:select where they want the xpath to appear. This could be made
more efficient (i generate all templates for all dynamic xpaths which is
less code for me to write but generates more templates than needed)

Evaluation stylesheet (this has original source doc filename hardcoded,
it could be a parameter)

<xsl:stylesheet version="1.0"
xmlns:x="data:,x"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template mode="a" match="person">
<xsl:value-of select="@name"/>
</xsl:template>

<xsl:template match="person">
Person: <xsl:value-of select="@name"/>
<xsl:apply-templates select="father|child"/>
</xsl:template>

<xsl:template x:match="father">
Father: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" x:select="@ref"/>
</xsl:template>

<xsl:template x:match="child">
Child: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" x:select="@ref"/>
</xsl:template>

</xsl:stylesheet>



generate real stylesheet
saxon -o eval2.xsl eval1.xsl eval.xsl

eval2.xsl has several templates expanded out. and looks like

<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:x="data:,x" version="1.0">
<xsl:template mode="a" match="person">
<xsl:value-of select="@name"/>
</xsl:template>

<xsl:template match="person">
Person: <xsl:value-of select="@name"/>
<xsl:apply-templates select="father|child"/>
</xsl:template>
<xsl:template match="father[@ref='../../person[2]']">
Father: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" select="../../person[2]"/>
</xsl:template>
<xsl:template match="father[@ref='../../person[1]']">
Father: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" select="../../person[1]"/>
</xsl:template>
<xsl:template match="child[@ref='../../person[2]']">
Child: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" select="../../person[2]"/>
</xsl:template>
<xsl:template match="child[@ref='../../person[1]']">
Child: <xsl:value-of select="@name"/>
<xsl:apply-templates mode="a" select="../../person[1]"/>
</xsl:template>

</xsl:stylesheet>

run this stylesheet on original source:

$ saxon eval.xml eval2.xsl
<?xml version="1.0" encoding="utf-8"?>

Person: bob
Father: charlie

Person: charlie
Child: bob


Jul 20 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: worli | last post by:
Hi All, I have a strange requirement. I have a dynamic input numeric data stream e.g. 2, 2, 4, 5 etc.... ( each input number range from 1 to 10 ). lets take a simple case where all inputs will...
4
by: David Dvali | last post by:
Hello. I have such XML file: <root> <elem1> <optional> Some data <optional> </elem1> </root>
2
by: Rich | last post by:
I am very new to ASP.NET, and did not see a similar error posted anywhere. Here is my situation. I followed the instructions in Peter Bromberg's excellent article "Host Winforms - based...
1
by: Filip Hendrickx | last post by:
Hi there. I want to generate elements, choosing the element name dynamically. So I tried to use attribute value templates: <xsl:element name="{$local-name($someNode)}"> <!-- Generate element...
6
by: luthriaajay | last post by:
How can I get the value of a particular element in the flwg XML using Java? Value of Document newSingleOrderDocument is: <?xml version="1.0" encoding="UTF-8"?> <FIXML...
2
by: luthriaajay | last post by:
I need some help to extract the LatestFillQuantity element value using XPATH. in Java. I am unable to extract the value of 10000. Please help as to what have I done wrong.? Help appreciated. ...
1
by: luthriaajay | last post by:
Using <xsl:value-of in XSL XML file <i:Details> <i:Stra> <stra:Desc>ABC</stra.Desc>
3
by: RhazeMondragon | last post by:
hello!!! i encounter problem by searching the records the database by using date value what would be the appropriate sql command that would fit in this problem.... thanks a lot!!!
3
by: thomas | last post by:
I want to use a priority_queue like STL data structure. But I found that priority_queue cannot update element value: only pop/ push is supported. I'm using priority_queue to implement the prim...
2
by: MATTXtwo | last post by:
I want to get input element value in a form not using Javascritp like: var NICNo=document.getElementById("NewICNo").value;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.