NodeSet Reduction

B

Bryan Galvin

Hi All,

I have been pulling my hair out with this one for the past three days,
using every combination of XPATH I can think of so even the tinniest
bit of help from anyone would be great.

I have a node set '$sub_set' that contains three <row> elements:

<row>
<field1>value1</field1><field2>value2</field2>
</row>
<row>
<field1>value3</field1><field2>value4</field2>
</row>
<row>
<field1>value1</field1><field2>value2</field2>
</row>

these have been extracted from:
<condition num="1">
<row>
<field1>value1</field1><field2>value2</field2>
</row>
<row>
<field1>value3</field1><field2>value4</field2>
</row>
</condition>
<condition num="2">
<row>
<field1>value1</field1><field2>value2</field2>
</row>
</condition>

I would like to reduce '$sub_set' down to just:
<row>
<field1>value3</field1><field2>value4</field2>
</row>

I will not list all the many XPATH expressions I have tried but this
is the closest I know that SHOULD work.
$current_row = $sub_set[1]
$sub_set[* != $current_row] - but this returns all three all original
nodes!

Does anyone have any ideas?

Bryan
 
B

Ben Edgington

I have a node set '$sub_set' that contains three <row> elements:

<row>
<field1>value1</field1><field2>value2</field2>
</row>
<row>
<field1>value3</field1><field2>value4</field2>
</row>
<row>
<field1>value1</field1><field2>value2</field2>
</row>

these have been extracted from:
<condition num="1">
<row>
<field1>value1</field1><field2>value2</field2>
</row>
<row>
<field1>value3</field1><field2>value4</field2>
</row>
</condition>
<condition num="2">
<row>
<field1>value1</field1><field2>value2</field2>
</row>
</condition>

I would like to reduce '$sub_set' down to just:
<row>
<field1>value3</field1><field2>value4</field2>
</row>

I'm not sure what you mean by "reduce '$sub_set' down". Do you just
mean that you want to extract the second node from the node-set?

If so, then what about this:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="/">

<!-- This sets up $sub_set with the three nodes, exactly
as you have it -->
<xsl:variable name="sub_set" select="foo/condition/row"/>

<!-- This extracts the second -->
<xsl:copy-of select="$sub_set[2]"/>

</xsl:template>

</xsl:stylesheet>


NB. I've made your XML properly-formed for this demonstration:

<foo>
<condition num="1">
<row>
<field1>value1</field1><field2>value2</field2>
</row>
<row>
<field1>value3</field1><field2>value4</field2>
</row>
</condition>
<condition num="2">
<row>
<field1>value1</field1><field2>value2</field2>
</row>
</condition>
</foo>


If that doesn't answer your question then perhaps you need to state it
more clearly.

Ben
 
A

A. Bolmarcich

I have been pulling my hair out with this one for the past three days,
using every combination of XPATH I can think of so even the tinniest
bit of help from anyone would be great.

I have a node set '$sub_set' that contains three <row> elements:

<row>
<field1>value1</field1><field2>value2</field2>
</row>
<row>
<field1>value3</field1><field2>value4</field2>
</row>
<row>
<field1>value1</field1><field2>value2</field2>
</row>

these have been extracted from:
<condition num="1">
<row>
<field1>value1</field1><field2>value2</field2>
</row>
<row>
<field1>value3</field1><field2>value4</field2>
</row>
</condition>
<condition num="2">
<row>
<field1>value1</field1><field2>value2</field2>
</row>
</condition>

I would like to reduce '$sub_set' down to just:
<row>
<field1>value3</field1><field2>value4</field2>
</row>

I will not list all the many XPATH expressions I have tried but this
is the closest I know that SHOULD work.
$current_row = $sub_set[1]
$sub_set[* != $current_row] - but this returns all three all original
nodes!

Does anyone have any ideas?

You may want to use

$sub_set[. != $current_row]

The != expression on two nodes sets is true if and only if there is a
node in the first node-set and a node in the second node-set such that
the result of performing the comparison on the string-values of the two
nodes is true.

The string value of $current_row is "\n value1value2\ " (the
concatenated string values of its descendants including the text nodes).

The $sub_set[* != $current_row] expression tests the three elements in
$sub_set named row. For each "row" element it tests whether the string
value of each subelement of the "row" element is not equal to the
string value of $current_row.

For the first "row" element it tests whether "value1" != $current_row
and whether "value2" != $current_row. The first "row" element is in the
resulting node set because both tests are true. A "row" element is in
the resulting node set if any of the tests are true. For similar
reasons the other "row" nodes are in the resulting node set too.

The $sub_set[. != $current_row] expression also tests the three elements
in $sub_set named row. For each "row" element it tests whether the
string value of the "row" element is not equal to the string value of
$current_row.

For the first "row" element it tests whether "\n value1value2\n "
!= $current_row. The first "row" element is not in the resulting node
set because the test is false. The second "row" node is in the resulting
node set because its test is true ("\n value3value4\n " !=
$current_row. The third "row" node is not in the resulting node set
because "\n value1value2\n " != $current_row.
 
B

Bryan Galvin

A. Bolmarcich,

Thanks for that. It solved the problem for me. The explanation was
useful because it helped clear-up my understanding of the W3C.org
specification on node set comparisons.

Bryan

I have been pulling my hair out with this one for the past three days,
using every combination of XPATH I can think of so even the tinniest
bit of help from anyone would be great.

I have a node set '$sub_set' that contains three <row> elements:

<row>
<field1>value1</field1><field2>value2</field2>
</row>
<row>
<field1>value3</field1><field2>value4</field2>
</row>
<row>
<field1>value1</field1><field2>value2</field2>
</row>

these have been extracted from:
<condition num="1">
<row>
<field1>value1</field1><field2>value2</field2>
</row>
<row>
<field1>value3</field1><field2>value4</field2>
</row>
</condition>
<condition num="2">
<row>
<field1>value1</field1><field2>value2</field2>
</row>
</condition>

I would like to reduce '$sub_set' down to just:
<row>
<field1>value3</field1><field2>value4</field2>
</row>

I will not list all the many XPATH expressions I have tried but this
is the closest I know that SHOULD work.
$current_row = $sub_set[1]
$sub_set[* != $current_row] - but this returns all three all original
nodes!

Does anyone have any ideas?

You may want to use

$sub_set[. != $current_row]

The != expression on two nodes sets is true if and only if there is a
node in the first node-set and a node in the second node-set such that
the result of performing the comparison on the string-values of the two
nodes is true.

The string value of $current_row is "\n value1value2\ " (the
concatenated string values of its descendants including the text nodes).

The $sub_set[* != $current_row] expression tests the three elements in
$sub_set named row. For each "row" element it tests whether the string
value of each subelement of the "row" element is not equal to the
string value of $current_row.

For the first "row" element it tests whether "value1" != $current_row
and whether "value2" != $current_row. The first "row" element is in the
resulting node set because both tests are true. A "row" element is in
the resulting node set if any of the tests are true. For similar
reasons the other "row" nodes are in the resulting node set too.

The $sub_set[. != $current_row] expression also tests the three elements
in $sub_set named row. For each "row" element it tests whether the
string value of the "row" element is not equal to the string value of
$current_row.

For the first "row" element it tests whether "\n value1value2\n "
!= $current_row. The first "row" element is not in the resulting node
set because the test is false. The second "row" node is in the resulting
node set because its test is true ("\n value3value4\n " !=
$current_row. The third "row" node is not in the resulting node set
because "\n value1value2\n " != $current_row.
 

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

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,830
Latest member
ZADIva7383

Latest Threads

Top