472,784 Members | 1,212 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

XPath / XSLT to extract 'overloaded' attribute

I want to create an XML configuration file which might look like

<REGION Name="Europe" WingDing="Blue">
<COUNTRY Name="UK" WingDing="white">
<TOWN Name="London" WingDing="Orange" />
</COUNTRY>
</REGION>
<REGION Name="NorthAmerica" WingDing="Yellow">
<COUNTRY Name="Canada">
<TOWN Name="Quebec" WingDing="Brown" />
<TOWN Name="Ontario" />
</COUNTRY>
</REGION>

Then I want to find a node (E.g. NorthAmerica/Canada/Ontario) and create an
XML Node with the values in that node PLUS any other values in nodes higher
up.

Specifically for any attribute I should pick the lowest occuring value.
Quebec would have a WIngDing of Yellow ('inheriting' from the Region node),
Quebec, Brown and London Orange.

Finding the node is easy with XPath, but I'm unsure how to pick the lowest
occuring attribute value, some kind of max(depth) operator would be required
and I do not seem to find one int my reference books. This sort of thing
can often be done with a chain of ifs, but it is inelegant.

Can any one make any suggestions?

thanks in advance

Iain
Jul 20 '05 #1
9 2829
I am sorry, but it is not clear what you want to achieve -- can you provide
a complete example and explantion?

I find this text quite contradictory:
Then I want to find a node (E.g. NorthAmerica/Canada/Ontario) and create an XML Node with the values in that node PLUS any other values in nodes higher up.

Specifically for any attribute I should pick the lowest occuring value.
Quebec would have a WIngDing of Yellow ('inheriting' from the Region node), Quebec, Brown and London Orange.
First you are speaking about NorthAmerica/Canada/Ontario , but then you
start speaking about Quebec ... ???

What is the meaning of this:
Specifically for any attribute I should pick the lowest occuring value.
Quebec would have a WIngDing of Yellow ('inheriting' from the Region node), Quebec, Brown and London Orange.
=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
"Iain" <id********@dircon.co.uk> wrote in message
news:dH***************@newsfep1-gui.server.ntli.net... I want to create an XML configuration file which might look like

<REGION Name="Europe" WingDing="Blue">
<COUNTRY Name="UK" WingDing="white">
<TOWN Name="London" WingDing="Orange" />
</COUNTRY>
</REGION>
<REGION Name="NorthAmerica" WingDing="Yellow">
<COUNTRY Name="Canada">
<TOWN Name="Quebec" WingDing="Brown" />
<TOWN Name="Ontario" />
</COUNTRY>
</REGION>

Then I want to find a node (E.g. NorthAmerica/Canada/Ontario) and create an XML Node with the values in that node PLUS any other values in nodes higher up.

Specifically for any attribute I should pick the lowest occuring value.
Quebec would have a WIngDing of Yellow ('inheriting' from the Region node), Quebec, Brown and London Orange.

Finding the node is easy with XPath, but I'm unsure how to pick the lowest
occuring attribute value, some kind of max(depth) operator would be required and I do not seem to find one int my reference books. This sort of thing
can often be done with a chain of ifs, but it is inelegant.

Can any one make any suggestions?

thanks in advance

Iain

Jul 20 '05 #2
Iain wrote:
I want to create an XML configuration file which might look like

<REGION Name="Europe" WingDing="Blue">
<COUNTRY Name="UK" WingDing="white">
<TOWN Name="London" WingDing="Orange" />
</COUNTRY>
</REGION>
<REGION Name="NorthAmerica" WingDing="Yellow">
<COUNTRY Name="Canada">
<TOWN Name="Quebec" WingDing="Brown" />
<TOWN Name="Ontario" />
</COUNTRY>
</REGION>

Then I want to find a node (E.g. NorthAmerica/Canada/Ontario) and create an
XML Node with the values in that node PLUS any other values in nodes higher
up.

Specifically for any attribute I should pick the lowest occuring value.
Quebec would have a WIngDing of Yellow ('inheriting' from the Region node),
Quebec, Brown and London Orange.

Finding the node is easy with XPath, but I'm unsure how to pick the lowest
occuring attribute value, some kind of max(depth) operator would be required
and I do not seem to find one int my reference books. This sort of thing
can often be done with a chain of ifs, but it is inelegant.

Can any one make any suggestions?


ancestor-or-self::*/@WindDing

may be what you're after. BTW: I'd call that "inheritance" rather than
"overloading".

Jul 20 '05 #3
I'm sorry if this is not clear.

I intended to indicate a configuration file with an hierarchical set of
nodes whereby TOWN was found in COUNTRY was found in REGION.

Towns at the bottom level in my example had names like Ontario, Quebec and
London.

Each town has a property (just made up as on example) called WingDing which
contains the name of a colour.

It is may aim that the WingDing property can be applied at any level as a
kind of default. SO if there is a 'WingDing' property set at a REGION level
then it will apply to all TOWNs in all COUNTRYs in that region unless
over-ridden at a COUNTRY or TOWN level.

What I want to do is to effectively find any give TOWN and a full set of
properties for that town regardless of if the property is set in the TOWN
node or the higher level COUNTRY or REGION node containing it.

My expectation was that I could do this using XSLT to find the node with an
XPath search and then to populate it with a known set of properties which
were present in that node or in a containing node.

I have never used XSLT (or much XPath) and it seemed that I could see
complex hard to maintain approaches, but rather hoped there was an elegant
approach which I had missed. Hence I threw myself on the mercy of the list!

Obviously in my real world applicaitons there could be many levels of
nesting of the nodes dozens or hundreds of different isntances at any level
and many attributes.

I would also be interested in applying the same techniques to elements, but
I imagine that solving the attribute case solves the element case too.

I hope this makes a bit more sense.

One of the actual applications is for a text formatting application where I
wish to be able to set a font at the top level of a set of XML based object
descriptions and override it in sub areas, panels, and specific text
instances. Holding the font in all places where it may be (for a complex
description) would be cumbersome and hard to maintain (the specific
application is to provide a layout template which I would wish to maintain
manually - requiring a font object in all bottom level text descriptions
would make for a lot of typing).

Iain
"Dimitre Novatchev" <dn********@yahoo.com> wrote in message
news:bq*************@ID-152440.news.uni-berlin.de...
I am sorry, but it is not clear what you want to achieve -- can you provide a complete example and explantion?

I find this text quite contradictory:
Then I want to find a node (E.g. NorthAmerica/Canada/Ontario) and create

an
XML Node with the values in that node PLUS any other values in nodes

higher
up.

Specifically for any attribute I should pick the lowest occuring value.
Quebec would have a WIngDing of Yellow ('inheriting' from the Region

node),
Quebec, Brown and London Orange.

First you are speaking about NorthAmerica/Canada/Ontario , but then you
start speaking about Quebec ... ???

What is the meaning of this:
Specifically for any attribute I should pick the lowest occuring value.
Quebec would have a WIngDing of Yellow ('inheriting' from the Region

node),
Quebec, Brown and London Orange.

=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
"Iain" <id********@dircon.co.uk> wrote in message
news:dH***************@newsfep1-gui.server.ntli.net...
I want to create an XML configuration file which might look like

<REGION Name="Europe" WingDing="Blue">
<COUNTRY Name="UK" WingDing="white">
<TOWN Name="London" WingDing="Orange" />
</COUNTRY>
</REGION>
<REGION Name="NorthAmerica" WingDing="Yellow">
<COUNTRY Name="Canada">
<TOWN Name="Quebec" WingDing="Brown" />
<TOWN Name="Ontario" />
</COUNTRY>
</REGION>

Then I want to find a node (E.g. NorthAmerica/Canada/Ontario) and create

an
XML Node with the values in that node PLUS any other values in nodes

higher
up.

Specifically for any attribute I should pick the lowest occuring value.
Quebec would have a WIngDing of Yellow ('inheriting' from the Region

node),
Quebec, Brown and London Orange.

Finding the node is easy with XPath, but I'm unsure how to pick the lowest occuring attribute value, some kind of max(depth) operator would be

required
and I do not seem to find one int my reference books. This sort of thing can often be done with a chain of ifs, but it is inelegant.

Can any one make any suggestions?

thanks in advance

Iain


Jul 20 '05 #4
I understand.

As Julian has pointed out, the following XPath expression provides the
attribute of the first ancestor (or self, if no ancestor has such attribute)
in document order:

ancestor-or-self::*/@WindDing

So, if a node does not have a "WindDing" attribute, it should inherit it
from the earliest ancestor that has it ?

Or, will this node inherit the attribute from the nearest ancestor ?

In case a node already has such-named attribute specified, then it should
not inherit from its ancestors ?
=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

"Iain" <id********@dircon.co.uk> wrote in message
news:cb**************@newsfep1-gui.server.ntli.net...
I'm sorry if this is not clear.

I intended to indicate a configuration file with an hierarchical set of
nodes whereby TOWN was found in COUNTRY was found in REGION.

Towns at the bottom level in my example had names like Ontario, Quebec and
London.

Each town has a property (just made up as on example) called WingDing which contains the name of a colour.

It is may aim that the WingDing property can be applied at any level as a
kind of default. SO if there is a 'WingDing' property set at a REGION level then it will apply to all TOWNs in all COUNTRYs in that region unless
over-ridden at a COUNTRY or TOWN level.

What I want to do is to effectively find any give TOWN and a full set of
properties for that town regardless of if the property is set in the TOWN
node or the higher level COUNTRY or REGION node containing it.

My expectation was that I could do this using XSLT to find the node with an XPath search and then to populate it with a known set of properties which
were present in that node or in a containing node.

I have never used XSLT (or much XPath) and it seemed that I could see
complex hard to maintain approaches, but rather hoped there was an elegant
approach which I had missed. Hence I threw myself on the mercy of the list!
Obviously in my real world applicaitons there could be many levels of
nesting of the nodes dozens or hundreds of different isntances at any level and many attributes.

I would also be interested in applying the same techniques to elements, but I imagine that solving the attribute case solves the element case too.

I hope this makes a bit more sense.

One of the actual applications is for a text formatting application where I wish to be able to set a font at the top level of a set of XML based object descriptions and override it in sub areas, panels, and specific text
instances. Holding the font in all places where it may be (for a complex
description) would be cumbersome and hard to maintain (the specific
application is to provide a layout template which I would wish to maintain
manually - requiring a font object in all bottom level text descriptions
would make for a lot of typing).

Iain
"Dimitre Novatchev" <dn********@yahoo.com> wrote in message
news:bq*************@ID-152440.news.uni-berlin.de...
I am sorry, but it is not clear what you want to achieve -- can you

provide
a complete example and explantion?

I find this text quite contradictory:
Then I want to find a node (E.g. NorthAmerica/Canada/Ontario) and create
an
XML Node with the values in that node PLUS any other values in nodes

higher
up.

Specifically for any attribute I should pick the lowest occuring
value. Quebec would have a WIngDing of Yellow ('inheriting' from the Region

node),
Quebec, Brown and London Orange.

First you are speaking about NorthAmerica/Canada/Ontario , but then you
start speaking about Quebec ... ???

What is the meaning of this:
Specifically for any attribute I should pick the lowest occuring value. Quebec would have a WIngDing of Yellow ('inheriting' from the Region

node),
Quebec, Brown and London Orange.

=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
"Iain" <id********@dircon.co.uk> wrote in message
news:dH***************@newsfep1-gui.server.ntli.net...
I want to create an XML configuration file which might look like

<REGION Name="Europe" WingDing="Blue">
<COUNTRY Name="UK" WingDing="white">
<TOWN Name="London" WingDing="Orange" />
</COUNTRY>
</REGION>
<REGION Name="NorthAmerica" WingDing="Yellow">
<COUNTRY Name="Canada">
<TOWN Name="Quebec" WingDing="Brown" />
<TOWN Name="Ontario" />
</COUNTRY>
</REGION>

Then I want to find a node (E.g. NorthAmerica/Canada/Ontario) and create
an
XML Node with the values in that node PLUS any other values in nodes

higher
up.

Specifically for any attribute I should pick the lowest occuring

value. Quebec would have a WIngDing of Yellow ('inheriting' from the Region

node),
Quebec, Brown and London Orange.

Finding the node is easy with XPath, but I'm unsure how to pick the

lowest occuring attribute value, some kind of max(depth) operator would be

required
and I do not seem to find one int my reference books. This sort of thing can often be done with a chain of ifs, but it is inelegant.

Can any one make any suggestions?

thanks in advance

Iain



Jul 20 '05 #5
Thanks, Dimitri, this looks like what I want. I shall try it out a bit
later on.

I didn't understand the reference to 'Julian' - I don't see an message form
him in htis thread, or have I missed something!

Iain
"Dimitre Novatchev" <dn********@yahoo.com> wrote in message
news:bq*************@ID-152440.news.uni-berlin.de...
I understand.

As Julian has pointed out, the following XPath expression provides the
attribute of the first ancestor (or self, if no ancestor has such attribute) in document order:

ancestor-or-self::*/@WindDing

So, if a node does not have a "WindDing" attribute, it should inherit it
from the earliest ancestor that has it ?

Or, will this node inherit the attribute from the nearest ancestor ?

In case a node already has such-named attribute specified, then it should
not inherit from its ancestors ?
=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

"Iain" <id********@dircon.co.uk> wrote in message
news:cb**************@newsfep1-gui.server.ntli.net...
I'm sorry if this is not clear.

I intended to indicate a configuration file with an hierarchical set of
nodes whereby TOWN was found in COUNTRY was found in REGION.

Towns at the bottom level in my example had names like Ontario, Quebec and
London.

Each town has a property (just made up as on example) called WingDing which
contains the name of a colour.

It is may aim that the WingDing property can be applied at any level as a kind of default. SO if there is a 'WingDing' property set at a REGION

level
then it will apply to all TOWNs in all COUNTRYs in that region unless
over-ridden at a COUNTRY or TOWN level.

What I want to do is to effectively find any give TOWN and a full set of
properties for that town regardless of if the property is set in the TOWN node or the higher level COUNTRY or REGION node containing it.

My expectation was that I could do this using XSLT to find the node with

an
XPath search and then to populate it with a known set of properties which were present in that node or in a containing node.

I have never used XSLT (or much XPath) and it seemed that I could see
complex hard to maintain approaches, but rather hoped there was an elegant approach which I had missed. Hence I threw myself on the mercy of the

list!

Obviously in my real world applicaitons there could be many levels of
nesting of the nodes dozens or hundreds of different isntances at any

level
and many attributes.

I would also be interested in applying the same techniques to elements,

but
I imagine that solving the attribute case solves the element case too.

I hope this makes a bit more sense.

One of the actual applications is for a text formatting application where I
wish to be able to set a font at the top level of a set of XML based

object
descriptions and override it in sub areas, panels, and specific text
instances. Holding the font in all places where it may be (for a

complex description) would be cumbersome and hard to maintain (the specific
application is to provide a layout template which I would wish to maintain manually - requiring a font object in all bottom level text descriptions
would make for a lot of typing).

Iain
"Dimitre Novatchev" <dn********@yahoo.com> wrote in message
news:bq*************@ID-152440.news.uni-berlin.de...
I am sorry, but it is not clear what you want to achieve -- can you

provide
a complete example and explantion?

I find this text quite contradictory:

> Then I want to find a node (E.g. NorthAmerica/Canada/Ontario) and

create an
> XML Node with the values in that node PLUS any other values in nodes
higher
> up.
>
> Specifically for any attribute I should pick the lowest occuring value. > Quebec would have a WIngDing of Yellow ('inheriting' from the Region
node),
> Quebec, Brown and London Orange.
>
First you are speaking about NorthAmerica/Canada/Ontario , but then you start speaking about Quebec ... ???

What is the meaning of this:

> Specifically for any attribute I should pick the lowest occuring value. > Quebec would have a WIngDing of Yellow ('inheriting' from the Region
node),
> Quebec, Brown and London Orange.
>
=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
"Iain" <id********@dircon.co.uk> wrote in message
news:dH***************@newsfep1-gui.server.ntli.net...
> I want to create an XML configuration file which might look like
>
> <REGION Name="Europe" WingDing="Blue">
> <COUNTRY Name="UK" WingDing="white">
> <TOWN Name="London" WingDing="Orange" />
> </COUNTRY>
> </REGION>
> <REGION Name="NorthAmerica" WingDing="Yellow">
> <COUNTRY Name="Canada">
> <TOWN Name="Quebec" WingDing="Brown" />
> <TOWN Name="Ontario" />
> </COUNTRY>
> </REGION>
>
> Then I want to find a node (E.g. NorthAmerica/Canada/Ontario) and create an
> XML Node with the values in that node PLUS any other values in nodes
higher
> up.
>
> Specifically for any attribute I should pick the lowest occuring value. > Quebec would have a WIngDing of Yellow ('inheriting' from the Region
node),
> Quebec, Brown and London Orange.
>
> Finding the node is easy with XPath, but I'm unsure how to pick the

lowest
> occuring attribute value, some kind of max(depth) operator would be
required
> and I do not seem to find one int my reference books. This sort of

thing
> can often be done with a chain of ifs, but it is inelegant.
>
> Can any one make any suggestions?
>
> thanks in advance
>
> Iain
>
>



Jul 20 '05 #6

"Iain" <id********@dircon.co.uk> wrote in message
news:pj*************@newsfep1-gui.server.ntli.net...
Thanks, Dimitri, this looks like what I want. I shall try it out a bit
later on.

I didn't understand the reference to 'Julian' - I don't see an message form him in htis thread, or have I missed something!


It is in the thread -- in case your newsreader does not show Julian's
message, see it here:

http://groups.google.com/groups?dq=&...3DN%26tab%3Dwg
=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

Jul 20 '05 #7
Thanks, Dimitre. I found julian in google, but not my newsreader (and
thanks julian!)!

I've been playing with ancestor-or-self and got something that seems to work
for attributes.

<xsl:copy-of select="ancestor-or-self::*/@ClipDirectory" />

but when I try and make it work for elements I get stuck. this is meant to
find the lowest MACHINE element which exists at or above the current node.

<xsl:copy-of select="ancestor-or-self::*/Machine[last()]" />

it returns all of them. I've tried various permutations which either return
nothing at all or all elements (or refuse to run!).

Hope you can help out here!

thanks

iain
Jul 20 '05 #8
In article <Ld****************@newsfep1-gui.server.ntli.net>,
Iain <id********@dircon.co.uk> wrote:

% but when I try and make it work for elements I get stuck. this is meant to
% find the lowest MACHINE element which exists at or above the current node.
%
% <xsl:copy-of select="ancestor-or-self::*/Machine[last()]" />

would

ancestor-or-self::*/Machine[not(descendant::Machine)]

do what you want?

In any case, one problem with your test is that last() is always going
to be seen as true. Your test should be position() = last(). Having said
that, it won't be testing what you want, because in that context, the
position is the position in the document tree, not the position in the
list of Machine nodes.

You could get position() and last() to do what you want using xsl:for-each

<xsl:for-each select="ancestor-or-self::*/Machine">
<xsl:if test='position() = last()'>
<xsl:copy-of select='.'/>
</xsl:if>
</xsl:for-each>
--

Patrick TJ McPhee
East York Canada
pt**@interlog.com
Jul 20 '05 #9
Thank you. The first suggestion, which I take it should find only those
Machine elements who don't have descendents with Machine elements, did *not*
work. I still got multiple results.

The second suggestion using the for loop and test worked fine! I was kind
of hoping that there was a neater way doing this, but, hey! it works.

Iain

"Patrick TJ McPhee" <pt**@interlog.com> wrote in message
news:bq**********@news.eusc.inter.net...
In article <Ld****************@newsfep1-gui.server.ntli.net>,
Iain <id********@dircon.co.uk> wrote:

% but when I try and make it work for elements I get stuck. this is meant to % find the lowest MACHINE element which exists at or above the current node. %
% <xsl:copy-of select="ancestor-or-self::*/Machine[last()]" />

would

ancestor-or-self::*/Machine[not(descendant::Machine)]

do what you want?

In any case, one problem with your test is that last() is always going
to be seen as true. Your test should be position() = last(). Having said
that, it won't be testing what you want, because in that context, the
position is the position in the document tree, not the position in the
list of Machine nodes.

You could get position() and last() to do what you want using xsl:for-each

<xsl:for-each select="ancestor-or-self::*/Machine">
<xsl:if test='position() = last()'>
<xsl:copy-of select='.'/>
</xsl:if>
</xsl:for-each>
--

Patrick TJ McPhee
East York Canada
pt**@interlog.com

Jul 20 '05 #10

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

Similar topics

7
by: Sebastian Petzelberger | last post by:
Hi group, please give me an example of a xpath with regex or better a link with examples. Thanks in advance, Sebastian
1
by: inquirydog | last post by:
Can anyone explain to me why the following XQuery expression (a simple xpath expression) returns a different result than the same expression in xslt? document("document.xml")//a/@b For the...
14
by: inquirydog | last post by:
Hi- One frusterating thing for me with xsl is that I don't know how to make xslt throw some sort of exception when a value-of path does not exist. For instance, suppose I have the following...
3
by: Andy Fish | last post by:
Hi, I just found this template in someone else's xslt (it's Microsoft's "word2html" stylesheet to convert WordProcessingML to HTML) <xsl:template match="WX:sect"> <xsl:variable...
1
by: Pathik | last post by:
Hi All, Currently I am trying to convert one xml file into another xml file which having different format than original xml file. my input xml file is like: <?xml version="1.0"...
2
by: akhilak | last post by:
Hi, I am using XPath to retrieve the node data from an XML file. I used the following code to extract the attribute data from the file. I manually entered the attribute name in the code and I am...
2
by: A. W. Dunstan | last post by:
I'm trying to figure out how XPath expressions work, and how I can use them to extract data into a particular format. I can extract the data I want using an XPath expression, but not with an XSLT...
0
by: Rina0 | last post by:
Cybersecurity engineering is a specialized field that focuses on the design, development, and implementation of systems, processes, and technologies that protect against cyber threats and...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...

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.