views:

253

answers:

3

Hi!

I am wanting to concatenate two nodeset values using XPath in XForms.

I know that XPath has a concat(string, string) function, but how would I go about concatenating two nodeset values?

BEGIN EDIT: I tried concat function.. I tried this.. and variations of it to make it work, but it doesn't

<xf:value ref="concat(instance('param_choices')/choice/root, .)"/>

END EDIT

Below is a simplified code example of what I am trying to achieve.

XForms model:

<xf:instance id="param_choices" xmlns="">
    <choices>
        <root label="Param Choices">/param</root>
        <choice label="Name">/@AAA</choice>
        <choice label="Value">/@BBB</choice>
    </choices>
</xf:instance>

XForms ui code that I currently have:

<xf:select ref="instance('criteria_data')/criteria/criterion" appearance="full">
    <xf:label>Param choices:</xf:label>    
    <br/>
    <xf:itemset nodeset="instance('param_choices')/choice">
        <xf:label ref="@label"></xf:label>
        <xf:value ref="."></xf:value>
    </xf:itemset>
</xf:select>    

(if user selects "Name" checkbox..) the XML output is:

<criterion>/@BBB</criterion>

However! I want to combine the root nodeset value with the current choice nodeset value.

Essentially:

<xf:value ref="concat(instance('param_choices')/choice/root, .)"/>

or

<xf:value ref="(instance('definition_choices')/choice/root) + ."/>

to achieve the following XML output:

<criterion>/param/@BBB</criterion>

Any suggestions on how to do this? (I am fairly new to XPath and XForms)

p.s. what I am asking makes sense to me when I typed it out, but if you have trouble figuring out what I'm asking, just let me know..

thanks!

A: 

The evaluation of an XPath expression can not modify the structure/contents of an XML document -- it only selects (a set of) existing nodes.

In order to produce a node that doesn't exist in the XML document, one must use other means in conjunction with XPath (such as XSLT).

Dimitre Novatchev
@Dimitre Novatchev: Thanks for the quick response. I guess my solution will be to hard code the root with each choice... so then choice looks like <choice>/param/@BBB<choice>.. There were reasons I wanted to avoid this, but I might be able to sacrifice those reasons.
developer
This answer is wrong, XForms makes it absolutely possible (indeed it is XForms' raison d'être).
Phil Booth
Phil-Booth: This answer is correct. It states a well-known fact about XPath, not anything about XForms.
Dimitre Novatchev
Dimitre, it may indeed be a well-known fact about XPath, but as an answer to this question about XForms, your answer is wrong.
Phil Booth
A: 

The problem is that you are using the ref attribute instead of the value attribute on your value element. The ref attribute is for binding elements to a single node, whereas the value attribute is for using the value from a resolved XPath expression.

There is also a small mistake in your XPath expression itself, so if you change your value element to this:

<xf:value value="concat(instance('param_choices')/root, .)" />

...you should find that it works correctly.

Phil Booth
Anonymous downvote, nice. Here is the part of the XForms spec that supports my answer (see the bit about @value):http://www.w3.org/TR/xforms11/#ui-selection-commonelems-value
Phil Booth
@Phil Booth: While I was very excited to see this solution, it did not work for me. With this solution: When I loaded the form, the checkboxes were preselected (which I do not want to occur), and when I submitted the data, no xml was produced at all.. :(
developer
@iHeartGreek: Which XForms processor are you using?
Phil Booth
A: 

Dynamic XPath expression construction is not yet supported in XForms. There is no such function as eval() for Javascript.

As a very limited workaround you could use an expression such as

/*[name() = substring-after(instance('param_choices')/root,'/')]/@*[name() = substring-after(.,'/@')]

Alain Couthures
Alain, why can't he just use `xf:value/@value` ?
Phil Booth
xf:value/@value would give the string '/param/@BBB', not the corresponding node value!
Alain Couthures
Yes, exactly. Perhaps we are reading different questions? From the question that I'm reading, it says `"to achieve the following XML output: <criterion>/param/@BBB</criterion>"`. What does your question say?
Phil Booth