2
votes

I have a strange dilemma....

First of all, I am stuck using XPath 1.0 only, that is what the ancient process the system is still using, so although I'd love to use 2.0, it's not going to happen.

I have a node as such: <Column Name="Letters">A, B, C, D, E, F, G, H, I</Column>

And I want the xpath to return a node list of these letters. Is this possible in any way? Is it possible to return a list of nodes derived from the number of letters present in the string? Is it possible to traverse the string, and somehow keep an index of where in the string you are for the next node?

Any suggestions, alternatives, and advice are welcome.

Thanks in advanced!

EDIT: If there were 9 instances of the "Letters" node as seen above, would it be possible to use(assuming I have removed all white space/commas): substring(Letters,1,1) to retrieve the first value, then when the program traverses to the next node, retrieve substring(Letters,2,1), etc, but instead of static indexes, have it return something like: substring(Letters,node2outof9,1)?

EDIT: EX)

<Column Name="Letters">A, B, C, D, E, F, G, H, I</Column> <Column Name="Letters">A, B, C, D, E, F, G, H, I</Column> <Column Name="Letters">A, B, C, D, E, F, G, H, I</Column> ...

Say I had the following pseudo-code:

foreach node in nodelist (Column @Name=Letters) substring(node, index?, 1)

Is there an xpath function or attribute I can use to give me the index for which node out of the nodelist I am currently traversing?

I'm thinking of a workaround by using the index of the current node to grab the letter I need. So I'm returning "Letters" 9 times, to grab one letter for each, 1 at a time.

I know this is a strange request, so I'll really appreciate any help...

UPDATE: The issue was resolved, but had to use a workaround as obviously this cannot be done using solely with XPATH. Thanks to all for the suggestions and advice. Answer to Jakrabbit for close-enough solution with what strange information I supplied.

2
What is processing the XPath? Typically you have XSLT or a programming language at your disposal. - Mark Thomas
Hi Mark- I do not have access to the handling program for this, all I see is the XML, and have to write sufficient XPath based on what the system is requiring. In this case, the xml is storing the data I need as a string of letters, and I need to give the letters one by one. So, it must be done in XPath and not the handler, if possible. Thanks for the response! - JWiley

2 Answers

1
votes

You could use something like:

fn:tokenize(Column[@Name="Letters"]/text(), ', ')

that would give you a nodeset of the letters. Then you could access it via an index var.

fn:tokenize(Column[@Name="Letters"]/text(), ', ')[i]

http://www.w3.org/TR/xpath-functions/#func-tokenize

Update: I think this would do the same thing in XPath 1.0 as long as there are no other delimiter characters and the result are actually letters (1 char long)

substring(translate(/Column[@Name="Letters"]/text(), ', ', ''), i, 1)
0
votes

XPath selects existing nodes, it does not create any new ones. Thus whether it is XPath 1.0 or 2.0 does not even matter, if you want to create a list of new nodes containing the letters you can't do that with XPath alone, you need a host language like XSLT or XQuery to create new nodes.