tags:

views:

386

answers:

2

Hi All,

I have an xml that contains two groups of related values:

<Rows>
    <!-- first group -->
    <Row>
        <Sequence>100</Sequence>
        <Value>+</Value>
    </Row>
    <Row>
        <Sequence>105</Sequence>
        <Value>+</Value>
    </Row>    
    <Row>
        <Sequence>110</Sequence>
        <Value>-</Value>
    </Row>
    <!-- second group -->
    <Row>
        <Sequence>150</Sequence>
        <Value>20</Value>
    </Row>
    <Row>
        <Sequence>155</Sequence>
        <Value>15</Value>
    </Row>    
    <Row>
        <Sequence>160</Sequence>
        <Value>90</Value>
    </Row>    
</Rows>

Each element of 1st group related to an element of 2nd group: sequence -> sequence + 50

I need to get a node set of nodes from 2nd group which related nodes from 1st group contain + sign (nodes with sequences 150 and 155).

These nodes are needed for future sorting and enumerating.

/Rows/Row[contains(/Rows/Row[Sequence = (./Sequence - 50)]/Value, '+')]

I tried the above xpath, but failed as ./ is referenced to the current context (within second brackets), but I need to access to the parent one (within first brackets).

Do anybody know a solution for that?

Regards, Aikin

P.S. substring(./Sequence - 50, 1, 3) is used to get

+1  A: 

There is a distinction between the context node (.) and the current node (current()) in XPath/XSLT. See also this related question:

Current node vs. Context node in XSLT/XPath?

In your example you would need to use current() to refer to the current node, e.g.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="Row">
    <Row1>
      <xsl:copy-of select="."/>
    </Row1>
    <Row2>
      <xsl:copy-of select="/Rows/Row[./Sequence = (current()/Sequence + 50) and current()/Value = '+']"/>
    </Row2>
  </xsl:template>
</xsl:stylesheet>

The above short XSLT snippet will copy each row with a corresponding row from the second group to the output document with the condition you gave in your question (difference is 50 and the first row has a + value).

0xA3
Thanks *divo*, I've already seen that post. The problem is that current() node is pointing to the root. Yeah, yeah, yeah I don't know xslt much I am an imperative programmer.About the preprocessing (xsl snippet above): it was an workaround.
Aikin
`current()` is not affected by anything you may write in XPath, it is affected by `xsl:apply-templates` and `xsl:for-each`. I believe his point was that you can always rewrite an XPath expression using `xsl:for-each` (possibly nested) and `xsl:if`, and then you can use `current()` as needed, bind it to variables, etc.
Pavel Minaev
A: 

Just turn the query upside down:

/Rows/Row[/Rows/Row[contains(Value, '+')]/Sequence = Sequence - 50]

It's also worth noting that xsl:key may be useful here to speed things up.

Pavel Minaev
Thanks a lot! It was to late tomorrow to change my mind :)
Aikin