XPath question.

D

Daniel Pitts

I have a document which has two elements: ValueOverride and ValueDefault
For example:
<MyDoc>
<ValueOverride>The override value</ValueOverride>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

I need a single XPath expression that will return ValueOverride if it is
non-empty, and ValueDefault otherwise.

Is this possible to do with XPath?

Thanks,
Daniel.
 
D

Daniel Pitts

I have a document which has two elements: ValueOverride and ValueDefault
For example:
<MyDoc>
<ValueOverride>The override value</ValueOverride>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

I need a single XPath expression that will return ValueOverride if it is
non-empty, and ValueDefault otherwise.

Is this possible to do with XPath?

Thanks,
Daniel.
Figured it out: ./ValueOverride|./ValueDefault[../ValueOverride='']
 
R

Roedy Green

That kind of problem is solved with XOR in Java, perhaps in XPATH too.
--
Roedy Green Canadian Mind Products
http://mindprod.com

The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.
~ Tom Cargill
 
M

Mike Schilling

Daniel said:
I have a document which has two elements: ValueOverride and
ValueDefault For example:
<MyDoc>
<ValueOverride>The override value</ValueOverride>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

I need a single XPath expression that will return ValueOverride if
it is non-empty, and ValueDefault otherwise.

Is this possible to do with XPath?

Thanks,
Daniel.
Figured it out: ./ValueOverride|./ValueDefault[../ValueOverride='']

What do you mean by "non-empty'? If you mean "has no text nodes for
children", that expression doesn't work for the document

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

It returns two nodes, the elements ValueOverride.and ValueDefault.

I'm guessing that what you want is the string whose parent is ValueOverride,
if there is one, and if not, the string whose parent is ValueDefault. In
that case, try

string(./ValueOverride[count(./text()) > 0]|./ValueDefault)

This uses the fact that string(), like the other conversion functions, when
applied to a node-set ignores any nodes after the first.
 
D

Daniel Pitts

Daniel said:
I have a document which has two elements: ValueOverride and
ValueDefault For example:
<MyDoc>
<ValueOverride>The override value</ValueOverride>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

I need a single XPath expression that will return ValueOverride if
it is non-empty, and ValueDefault otherwise.

Is this possible to do with XPath?

Thanks,
Daniel.
Figured it out: ./ValueOverride|./ValueDefault[../ValueOverride='']

What do you mean by "non-empty'? If you mean "has no text nodes for
children", that expression doesn't work for the document

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

It returns two nodes, the elements ValueOverride.and ValueDefault.

I'm guessing that what you want is the string whose parent is ValueOverride,
if there is one, and if not, the string whose parent is ValueDefault. In
that case, try

string(./ValueOverride[count(./text())> 0]|./ValueDefault)

This uses the fact that string(), like the other conversion functions, when
applied to a node-set ignores any nodes after the first.
Strange, the solution I posted worked just fine for me.
 
M

Mike Schilling

Daniel said:
Daniel said:
On 3/12/2010 2:56 PM, Daniel Pitts wrote:
I have a document which has two elements: ValueOverride and
ValueDefault For example:
<MyDoc>
<ValueOverride>The override value</ValueOverride>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

I need a single XPath expression that will return ValueOverride if
it is non-empty, and ValueDefault otherwise.

Is this possible to do with XPath?

Thanks,
Daniel.

Figured it out: ./ValueOverride|./ValueDefault[../ValueOverride='']

What do you mean by "non-empty'? If you mean "has no text nodes for
children", that expression doesn't work for the document

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

It returns two nodes, the elements ValueOverride.and ValueDefault.

I'm guessing that what you want is the string whose parent is
ValueOverride, if there is one, and if not, the string whose parent
is ValueDefault. In that case, try

string(./ValueOverride[count(./text())> 0]|./ValueDefault)

This uses the fact that string(), like the other conversion
functions, when applied to a node-set ignores any nodes after the
first.
Strange, the solution I posted worked just fine for me.

Then you must not have applied it to

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

And perhaps that's not a document you need to apply it to. It was difficult
to tell from the description of the problem.
 
D

Daniel Pitts

Daniel said:
Daniel Pitts wrote:
On 3/12/2010 2:56 PM, Daniel Pitts wrote:
I have a document which has two elements: ValueOverride and
ValueDefault For example:
<MyDoc>
<ValueOverride>The override value</ValueOverride>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

I need a single XPath expression that will return ValueOverride if
it is non-empty, and ValueDefault otherwise.

Is this possible to do with XPath?

Thanks,
Daniel.

Figured it out: ./ValueOverride|./ValueDefault[../ValueOverride='']

What do you mean by "non-empty'? If you mean "has no text nodes for
children", that expression doesn't work for the document

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

It returns two nodes, the elements ValueOverride.and ValueDefault.

I'm guessing that what you want is the string whose parent is
ValueOverride, if there is one, and if not, the string whose parent
is ValueDefault. In that case, try

string(./ValueOverride[count(./text())> 0]|./ValueDefault)

This uses the fact that string(), like the other conversion
functions, when applied to a node-set ignores any nodes after the
first.
Strange, the solution I posted worked just fine for me.

Then you must not have applied it to

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

And perhaps that's not a document you need to apply it to. It was difficult
to tell from the description of the problem.
Are you saying that <ValueOverride></ValueOverride> will have a
different value than <ValueOverride/>?

In theory, I won't have a case where ValueOverride uses the shortcut. I
should verify that my code works with either, but I'd be surprised if it
doesn't. When I have some time, I'll write up an SSCCE to see.
 
M

Mike Schilling

Daniel said:
Daniel said:
On 3/12/2010 8:31 PM, Mike Schilling wrote:
Daniel Pitts wrote:
On 3/12/2010 2:56 PM, Daniel Pitts wrote:
I have a document which has two elements: ValueOverride and
ValueDefault For example:
<MyDoc>
<ValueOverride>The override value</ValueOverride>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

I need a single XPath expression that will return ValueOverride
if it is non-empty, and ValueDefault otherwise.

Is this possible to do with XPath?

Thanks,
Daniel.

Figured it out:
./ValueOverride|./ValueDefault[../ValueOverride='']

What do you mean by "non-empty'? If you mean "has no text nodes
for children", that expression doesn't work for the document

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

It returns two nodes, the elements ValueOverride.and ValueDefault.

I'm guessing that what you want is the string whose parent is
ValueOverride, if there is one, and if not, the string whose parent
is ValueDefault. In that case, try

string(./ValueOverride[count(./text())> 0]|./ValueDefault)

This uses the fact that string(), like the other conversion
functions, when applied to a node-set ignores any nodes after the
first.
Strange, the solution I posted worked just fine for me.

Then you must not have applied it to

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

And perhaps that's not a document you need to apply it to. It was
difficult to tell from the description of the problem.
Are you saying that <ValueOverride></ValueOverride> will have a
different value than <ValueOverride/>?

No, they're identical. But if you have either one of them, it'll match your
XPath expression, even though it doesn't specify a value (or, to be more
precise, doesn't have any child nodes that are text.)
 
D

Daniel Pitts

Daniel said:
Daniel Pitts wrote:
On 3/12/2010 8:31 PM, Mike Schilling wrote:
Daniel Pitts wrote:
On 3/12/2010 2:56 PM, Daniel Pitts wrote:
I have a document which has two elements: ValueOverride and
ValueDefault For example:
<MyDoc>
<ValueOverride>The override value</ValueOverride>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

I need a single XPath expression that will return ValueOverride
if it is non-empty, and ValueDefault otherwise.

Is this possible to do with XPath?

Thanks,
Daniel.

Figured it out:
./ValueOverride|./ValueDefault[../ValueOverride='']

What do you mean by "non-empty'? If you mean "has no text nodes
for children", that expression doesn't work for the document

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

It returns two nodes, the elements ValueOverride.and ValueDefault.

I'm guessing that what you want is the string whose parent is
ValueOverride, if there is one, and if not, the string whose parent
is ValueDefault. In that case, try

string(./ValueOverride[count(./text())> 0]|./ValueDefault)

This uses the fact that string(), like the other conversion
functions, when applied to a node-set ignores any nodes after the
first.
Strange, the solution I posted worked just fine for me.

Then you must not have applied it to

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

And perhaps that's not a document you need to apply it to. It was
difficult to tell from the description of the problem.
Are you saying that<ValueOverride></ValueOverride> will have a
different value than<ValueOverride/>?

No, they're identical. But if you have either one of them, it'll match your
XPath expression, even though it doesn't specify a value (or, to be more
precise, doesn't have any child nodes that are text.)
So the result will be "The default value", which is what I want. Or are
you saying it is document order-dependent?

If the latter is the case, then my code still works for my situation,
but should be fixed in either case ;-)
 
M

Mike Schilling

Daniel said:
Daniel said:
On 3/13/2010 6:13 PM, Mike Schilling wrote:
Daniel Pitts wrote:
On 3/12/2010 8:31 PM, Mike Schilling wrote:
Daniel Pitts wrote:
On 3/12/2010 2:56 PM, Daniel Pitts wrote:
I have a document which has two elements: ValueOverride and
ValueDefault For example:
<MyDoc>
<ValueOverride>The override value</ValueOverride>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

I need a single XPath expression that will return ValueOverride
if it is non-empty, and ValueDefault otherwise.

Is this possible to do with XPath?

Thanks,
Daniel.

Figured it out:
./ValueOverride|./ValueDefault[../ValueOverride='']

What do you mean by "non-empty'? If you mean "has no text nodes
for children", that expression doesn't work for the document

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

It returns two nodes, the elements ValueOverride.and
ValueDefault. I'm guessing that what you want is the string whose
parent is
ValueOverride, if there is one, and if not, the string whose
parent is ValueDefault. In that case, try

string(./ValueOverride[count(./text())> 0]|./ValueDefault)
This uses the fact that string(), like the other conversion
functions, when applied to a node-set ignores any nodes after the
first.
Strange, the solution I posted worked just fine for me.

Then you must not have applied it to

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

And perhaps that's not a document you need to apply it to. It was
difficult to tell from the description of the problem.
Are you saying that<ValueOverride></ValueOverride> will have a
different value than<ValueOverride/>?

No, they're identical. But if you have either one of them, it'll
match your XPath expression, even though it doesn't specify a value
(or, to be more precise, doesn't have any child nodes that are text.)
So the result will be "The default value", which is what I want. Or
are you saying it is document order-dependent?

As I said to begin with, applying

../ValueOverride|./ValueDefault[../ValueOverride='']

to

<MyDoc>
<ValueOverride/>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

or, equivalently,

<MyDoc>
<ValueOverride></ValueOverride>
<ValueDefault>The default value</ValueDefault>
</MyDoc>

returns a node set with two nodes: the element ValueOverride and the element
ValueDefault (in document order). If that works for you, fine.
 

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

Similar Threads

pythojn/xpath question... 1
ATTLIST and enumerations 4
XML Xpath interrogation 0
Xpath 5
Register Question 0
Using XPath to copy nodes 0
Using XPath to copy nodes 1
LibXML (XPATH) and escape 0

Members online

No members online now.

Forum statistics

Threads
473,981
Messages
2,570,188
Members
46,731
Latest member
MarcyGipso

Latest Threads

Top