473,473 Members | 1,512 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Any simple way to obtain a "dynamically-defined" nodeset?

Hello,

I am not sure the subject of my post adequately describes the problem I
am trying to solve, so I think a specific example would be helpful.

Let's say there are XML descriptions of products like this one:

<!-- File: Products.xml -->
...
<Product id="p1">
<Title>....</Title>
...
<PricingInfo>
<RegularPrice>100</RegularPrice>
<Discount>25</Discount>
...
</PricingInfo>
...
<ShippingInfo>
<Cost>9.95</Cost>
<MaxDelay>1 business day</MaxDelay>
...
</ShippingInfo>
...
</Product>

The key thing here is that the schema of <Productis not "flat" - it
contains elements with subelements, which may also have subelements,
and so on...

Now, let's say that I want to have an XML file that describes some sort
of an HTML page template which, in particular, refers to certain
attributes of <Product>s. Something along these lines:

<!-- File: PageTemplate.xml -->
...
<section>General</section>
<p>Title: <ProductProperty rxpath="Title"/></p>
<section>Shipping Info</section>
<p>Cost: <ProductProperty rxpath="ShippingInfo/Cost"/></p>
<p>Delay: <ProductProperty rxpath="ShippingInfo/Delay"/></p>
...

Finally, in an XSL file, whose templates are supposed to be applied to
PageTemplate.xml, I would like to write something like this:

<!-- File: ProductPage.xsl -->
...
<xs:template match="ProductProperty">
<!-- The parameter contains a nodeset from Products.xml -->
<!-- Or there could be a variable with the same contents... -->
<xs:param name="nsProduct" tunnel="yes"/>
<!-- And below is where the fun begins... -->
<xs:apply-templates
select="$nsProduct/*[name()=current()/@rxpath]"/>
</xs:template>

The problem is: I do not know what could I specify the @select
attribute of the <xs:apply-templateselement to retrieve exactly the
sub-nodeset of <Productelement defined by the @rxpath attribute of
the <ProductPropertyelement.

The expression I wrote above -- $nsProduct/*[name()=current()/@rxpath]
-- works fine for @rxpaths that specify direct children of the
<Productelement (like "Title"), but obviously does not work for any
ancestor elements (like "ShippingInfo/Cost"). So I guess I am looking
for a way to dynamically obtain a sub-nodeset of a specified "origin
nodeset" (in my example, it is defined by $nsProduct) using specified
"subpath" inside that nodeset.

In some sense, the problem is similar to what XForms are trying to
achieve: provide XML description of a data model, XML description of a
view of that data model, and bindings between view elements and data
model elements. In my case, "bindings" are supposed to be very
simplistic - just plain relative XPath expressions...

If anyone knows the trick that could let me do what I want (or
something really close to what I want) using XSLT 2.0 and XPath 2.0,
please advise. In fact, any comments would be appreciated.

Thank you,
Yarik.

Aug 21 '06 #1
2 1640
Dynamic interpretation of XPaths from variables is not supported in XSLT
.... but may be possible in some specific processors via extension
functions. See
http://www.exslt.org/dyn/

Instead, I'd consider writing your "template file" so it can be executed
directly as a stylesheet. One approach to doing so is shown in the XSLT
spec itself:
http://www.w3.org/TR/xslt#result-element-stylesheet

Or, if you really want to separate the binding stage from the styling
stage, you could consider two-pass transformation -- one pass to extract
the data and put it in standard form, and a second to get it from that
into your presentation form.

--
() ASCII Ribbon Campaign | Joe Kesselman
/\ Stamp out HTML e-mail! | System architexture and kinetic poetry
Aug 22 '06 #2
Joe, thank you much for quick and thorough response!

Joe Kesselman wrote:
Dynamic interpretation of XPaths from variables is not supported
in XSLT ... but may be possible in some specific processors
via extension functions.
I'm using Saxon, and it does not seem to support dyn: extensions. But,
even if it did, using EXSLT would be my last resort. (Or next to last.
:-))
Instead, I'd consider writing your "template file" so it can be executed
directly as a stylesheet. One approach to doing so is shown in the XSLT
spec itself:
http://www.w3.org/TR/xslt#result-element-stylesheet
This probably would be my first choice should I lose my battle for "a
la XForms" approach...
Or, if you really want to separate the binding stage from the styling
stage, you could consider two-pass transformation...
I guess, this would be my second choice...

In the meantime, I did some quick-and-dirty experiments and... it turns
out that "vanilla" XSLT 2.0 is not as weak as I thought. If anyone is
interested, my experiment yielded the following interesting, yet very
simple, custom function (i.e. function template):

<xs:function name="custom:path" xmlns:custom="custom">
<xs:param name="nsNode"/>
<xs:param name="nsRoot"/>

<xs:if test="not($nsNode is $nsRoot)">
<xs:value-of
select="concat(custom:path($nsNode/parent::node(),$nsRoot), '/',
name($nsNode))"/>
</xs:if>

</xs:function>

It takes two nodes and returns a string that represents a path from
$nsRoot to $nsNode (assuming that $nsNode is a descendant of $nsRoot).

Now, taking my initial example, I can use this nice function like this:

<xs:template match="ProductProperty">
<!-- The parameter contains a nodeset from Products.xml -->
<!-- Or there could be a variable with the same contents... -->

<xs:param name="nsProduct" tunnel="yes"/>
<!-- And below is where the fun begins... -->
<xs:apply-templates select="$nsProduct/*[custom:path(.,
$nsProduct) = current()/@rxpath]"/>
</xs:template>

Maybe this is not the most elegant way to do it, but it appears to be
working just fine. Moreover, I suspect that, with some additional
effort, this function could be enhanced to handle more intricate cases.
But... at 4 o'clock in the morning I would not bet my head on this...
:-)

The more I use XSLT 2.0, the more I like it (and the more XSLT 1.0
feels like a stone-age tool :-).

Aug 25 '06 #3

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

Similar topics

3
by: Phil Powell | last post by:
'GET THE HTML CONTENT FOR DISPLAY BAND ORIGIN Dim bandOriginDropdown On Error Resume Next set scraper = Server.CreateObject("Microsoft.XMLHTTP") if err then bandOriginDropdown = "" else...
81
by: Matt | last post by:
I have 2 questions: 1. strlen returns an unsigned (size_t) quantity. Why is an unsigned value more approprate than a signed value? Why is unsighned value less appropriate? 2. Would there...
1
by: Action | last post by:
Let's say class parent class B : parent class C : parent ....etc. (may add later......so I don't know how many classes will there...) I wanna to let the user type in the class name and...
0
by: tommy | last post by:
hello everybody, i haved read a few articles about, how to create controls in asp.net dynamically! i have tested it -- all works fine.... but....now it comes--> HOW create controls...
3
by: Ahmed Ayoub | last post by:
i forgot how to create Textboxes & Label Dynamically. Meaning, i want to make them .. initialize their position .. and view them and interact with them.
14
by: Alf P. Steinbach | last post by:
Not yet perfect, but: http://home.no.net/dubjai/win32cpptut/special/pointers/ch_01.pdf http://home.no.net/dubjai/win32cpptut/special/pointers/ch_01_examples.zip To access the table of...
9
by: Anubhav Jain | last post by:
Hi, I am having few .net source files(.cs or .vb) and I want to dynamically generate the corresponding .net project file(.csproj or .vbproj) for them without using visual studio.So that I could...
2
by: loga123 | last post by:
Hi All, I am new to .net. I am creating a text box in a "button1" "click event" dynamically based on user input. Name of the text box and ID of the text box contro are set dynamically in the...
1
by: komaladevi | last post by:
can any one help me in writing acode -"how to edit "edit item template" dynamically""
5
by: akonsu | last post by:
hello, i need to add properties to instances dynamically during run time. this is because their names are determined by the database contents. so far i found a way to add methods on demand: ...
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:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
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,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

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.