we7313

I can't fugure out how to write an xpath to do the following in xpath 1.0:

Doc

<Plane>

<Seats Number="1" Window="No"/>

<Seats Number="2" Window="Yes"/>

</Plane>

I would like to concatinate the @Number & @Window fields on each node set returned

Desired Results:

1^NO

2^Yes

The problem is if I use concat in xpath 1.0 I only get a single string result.

Any ideas




Re: XML and the .NET Framework Is this only possible in XPath 2.0

Sinan Ussakli - MSFT

Hi,

The following XPath command will return you a string that contains the first element's number and window concataneted.

concat(//Seats/@Number,' and ',//Seats/@Window)

When you use concat, it return only stringtype, therefore it's not possible to navigate over it. There might be a hack to get around of this but I'm not aware of such thing.






Re: XML and the .NET Framework Is this only possible in XPath 2.0

we7313

Right, that is the problem I need multiple node set result.

Concat with only return a single string...






Re: XML and the .NET Framework Is this only possible in XPath 2.0

Dimitre_Novatchev - MSFT

This is easy if the number of "Seats" elements is known (or can be obtained and then the XPath expression can be dynamically generated.

In case one knows an expected maximum number of "Seats" elements, it is still possible to use an XPath expression like the following:

concat(
/*/*[not(1 > count(/*/*))][1]/@*[1],
substring('^', 1, not(1 > count(/*/*))),
/*/*[not(1 > count(/*/*))][1]/@*[2], '&#xA;',

/*/*[not(2 > count(/*/*))][2]/@*[1],
substring('^', 1, not(2 > count(/*/*))),
/*/*[not(2 > count(/*/*))][2]/@*[2], '&#xA;',

/*/*[not(3 > count(/*/*))][3]/@*[1],
substring('^', 1, not(3 > count(/*/*))),
/*/*[not(3 > count(/*/*))][3]/@*[2], '&#xA;',

/*/*[not(4 > count(/*/*))][4]/@*[1],
substring('^', 1, not(4 > count(/*/*))),
/*/*[not(4 > count(/*/*))][4]/@*[2], '&#xA;',

/*/*[not(5 > count(/*/*))][5]/@*[1],
substring('^', 1, not(5 > count(/*/*))),
/*/*[not(5 > count(/*/*))][5]/@*[2], '&#xA;',

/*/*[not(6 > count(/*/*))] [ 6 ] /@*[1],
substring('^', 1, not(6 > count(/*/*))),
/*/*[not(6 > count(/*/*))] [ 6 ]/@*[2], '&#xA;',

/*/*[not(7 > count(/*/*))][7]/@*[1],
substring('^', 1, not(7 > count(/*/*))),
/*/*[not(7 > count(/*/*))][7]/@*[2], '&#xA;',

/*/*[not(8 > count(/*/*))] [ 8 ]/@*[1],
substring('^', 1, not(8 > count(/*/*))),
/*/*[not(8 > count(/*/*))] [ 8 ]/@*[2], '&#xA;',

/*/*[not(9 > count(/*/*))][9]/@*[1],
substring('^', 1, not(9 > count(/*/*))),
/*/*[not(9 > count(/*/*))][9]/@*[2], '&#xA;',

/*/*[not(10 > count(/*/*))][10]/@*[1],
substring('^', 1, not(10 > count(/*/*))),
/*/*[not(10 > count(/*/*))][10]/@*[2], '&#xA;',

/*/*[not(11 > count(/*/*))][11]/@*[1],
substring('^', 1, not(11 > count(/*/*))),
/*/*[not(11 > count(/*/*))][11]/@*[2], '&#xA;'

)

When this XPath expression is evaluated on the xml document below:

<Plane>

<Seats Number="1" Window="No"/>

<Seats Number="2" Window="Yes"/>

<Seats Number="3" Window="No"/>

<Seats Number="4" Window="Yes"/>

</Plane>

the wanted result will be produced:

1^No
2^Yes
3^No
4^Yes

Cheers,
Dimitre Novatchev





Re: XML and the .NET Framework Is this only possible in XPath 2.0

we7313

In my example (which is just what it is) the attribute @Number on seat is not a sequence or count. It reference's a possition on the plan. Let me modify the XML example to make this clear:

<Plane>

<Seats Number="512" Window="No"/>

<Seats Number="322" Window="Yes"/>

<Seats Number="122" Window="No"/>

<Seats Number="340" Window="Yes"/>

</Plane>

This might be used to represent inventory availability.

The result must be able to combine the 2 attributes in result node sets.






Re: XML and the .NET Framework Is this only possible in XPath 2.0

Dimitre_Novatchev - MSFT

we7313 wrote:

In my example (which is just what it is) the attribute @Number on seat is not a sequence or count. It reference's a possition on the plan. Let me modify the XML example to make this clear:

<Plane>

<Seats Number="512" Window="No"/>

<Seats Number="322" Window="Yes"/>

<Seats Number="122" Window="No"/>

<Seats Number="340" Window="Yes"/>

</Plane>

This might be used to represent inventory availability.

The result must be able to combine the 2 attributes in result node sets.

In the solution provided, the "Number" attribute is not used at all, so no assumption is being made that it will denote something specific.

The solution works for your last example, producing, as required:

512^No
322^Yes
122^No
340^Yes

Cheers,
Dimitre Novatchev





Re: XML and the .NET Framework Is this only possible in XPath 2.0

-Anton Lapounov

I guess this may be simplified to

translate(concat(
  normalize-space(concat(/*/*[1]/@*[1], ' ', /*/*[1]/@*[2])), '&#xA;',
  normalize-space(concat(/*/*[2]/@*[1], ' ', /*/*[2]/@*[2])), '&#xA;',
  normalize-space(concat(/*/*[3]/@*[1], ' ', /*/*[3]/@*[2])), '&#xA;',
  normalize-space(concat(/*/*[4]/@*[1], ' ', /*/*[4]/@*[2])), '&#xA;',
  normalize-space(concat(/*/*[5]/@*[1], ' ', /*/*[5]/@*[2])), '&#xA;',
  normalize-space(concat(/*/*[ 6]/@*[1], ' ', /*/*[ 6]/@*[2])), '&#xA;',
  normalize-space(concat(/*/*[7]/@*[1], ' ', /*/*[7]/@*[2])), '&#xA;',
  normalize-space(concat(/*/*[ 8]/@*[1], ' ', /*/*[ 8]/@*[2])), '&#xA;',
  normalize-space(concat(/*/*[9]/@*[1], ' ', /*/*[9]/@*[2])), '&#xA;',
  normalize-space(concat(/*/*[10]/@*[1], ' ', /*/*[10]/@*[2])), '&#xA;',
  normalize-space(concat(/*/*[11]/@*[1], ' ', /*/*[11]/@*[2])), '&#xA;'
), ' ', '^')





Re: XML and the .NET Framework Is this only possible in XPath 2.0

we7313

The problem is that I need the results to come back in seperate node sets. I don't need a way to add a line return to make it look like it multiple node sets.

We have an application that takes in an xpath and executes it against a doc. If the results have multiple node results it seeds them in the database with a sequence. Every example provided so far only returns a single string. I need a 1 to many node set.






Re: XML and the .NET Framework Is this only possible in XPath 2.0

Dimitre_Novatchev - MSFT

An XPath (1.0 or 2.0) expression cannot "create node-sets" -it can select a set of nodes that exist on the document(s) against which the XPath expression is evaluated.

Also, it is not at all clear what you mea by "concatinate node-sets" In XPath concatenation is an operation defined on two strings, not on node-sets. Probably you meant the union operation But it doesn't produce two node-sets -- just one node-set, which is the union of the two arguments passed to the union operator.

An XPath 2.0 can create a sequence of nodes (or other items), which is very different from a node-set (for example, the same node my occur more than once in a sequence).

Therefore, could you, please, provide a more precise definition of your problem -- a complete small example would be most appropriate.

Cheers,
Dimitre Novatchev.





Re: XML and the .NET Framework Is this only possible in XPath 2.0

we7313

Ok I'll try again:

example:

XML

<Plane>

<Seats Number="512" Window="No"/>

<Seats Number="322" Window="Yes"/>

<Seats Number="122" Window="No"/>

<Seats Number="340" Window="Yes"/>

</Plane>

The following xpath would return multiple nodes.

/Plane/Seats

This is what I'm refefering to as a node set. I would like to be able to get the @Number & @Window value back in a node set like this (except stringing them together). Which sounds impossible because I guess this would be creating a new node set & populating the new concatinated data.

I do not want a string returned.

So that pretty much sums up the problem. I can do this in xpath 2.0.






Re: XML and the .NET Framework Is this only possible in XPath 2.0

Dimitre_Novatchev - MSFT

Yes,

however you confused everybody by using a phrase like "(except stringing them together)".

What you actually wanted is by only using a single XPath expression to create a single text node out of two attribute nodes and to return the sequence of the nodes, produced in this way.

This is possible in XPath 2.0, because of the "for" expression.

One could use XSLT 1.0 for this purpose, or one could code an extension function and make it accessible in the XPath evaluation context, that would create the new text node.

Cheers,
Dimitre Novatchev