From: Mike Schilling on
Daniel Pitts wrote:
> On 3/15/2010 11:25 AM, Mike Schilling wrote:
>> Daniel Pitts wrote:
>>> 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.