I'm using Xpath 1.0, so I can't use 'distinct-values'. Is there a work-
around? Alternative implementation?
Thanks!
> I'm using Xpath 1.0, so I can't use 'distinct-values'. Is there a work-
> around? Alternative implementation?
With the XML being e.g.
<root>
<foo>a</foo>
<foo>b</foo>
<foo>a</foo>
<foo>c</foo>
<foo>c</foo>
<foo>d</foo>
</root>
the XPath /root/foo[not(. = preceding-sibling::foo)] selects only
distinct 'foo' elements e.g.
<foo>a</foo>
<foo>b</foo>
<foo>c</foo>
<foo>d</foo>
If you use XPath 1.0 inside XSLT 1.0 then you can also use Muenchian
grouping to group and process only the first item in each group.
--
Martin Honnen --- MVP XML
http://msmvps.com/blogs/martin_honnen/
Thanks for your reply!
For me, this does not work because the nodes are in a variable, that I
selected from another node-set. And my <foo> nodes do not have a
common parent.
I did something like this: <xsl:variable name="fie" select="root/foo
[..some predicate here....].
Maybe I can build a new node set with a root node with the _selected_
foos beneath? And then do the preceding-sibling trick?
The Muenchian approach is also difficult (impossible?) to apply,
because xsl:key is a top-level node only.
Again, thanks very much for your help!
> For me, this does not work because the nodes are in a variable, that I
> selected from another node-set. And my <foo> nodes do not have a
> common parent.
> I did something like this: <xsl:variable name="fie" select="root/foo
> [..some predicate here....].
> Maybe I can build a new node set with a root node with the _selected_
> foos beneath? And then do the preceding-sibling trick?
You will need to show the relevant XML and explain which nodes you are
interested in, then we can hopefully sort it out.
> The Muenchian approach is also difficult (impossible?) to apply,
> because xsl:key is a top-level node only.
xsk:key is a top level element but you can certainly specify a match
pattern for nodes at any level. For instance
<xsl:key name="k1" match="foo[your predicate here]" match="."/>
is certainly possible to define the key only for 'foo' elements
fulfilling your predicate.
Ok, here is what I have:
This is the XML input:
<root>
<foo @name="1">a</foo>
<foo @name="1">b</foo>
<foo @name="1">a</foo>
<foo @name="2">c</foo>
<foo @name="2">c</foo>
<foo @name="2">d</foo>
</root>
And here is what I would have done with distinct-values:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.0">
<!-- root template: -->
<xsl:template match="/root">
<xsl:call-template name="fum">
<xsl:with-param name="in" select="."/>
</xsl:call-template>
</xsl:template>
<!-- sub-template: -->
<xsl:template name="fum">
<xsl:param name="in"/>
<!-- this is the input -->
<xsl:variable name="fie" select="$in/foo[@name='1']" />
<xsl:variable name="fum" select="distinct-values($fie)" />
</xsl:template>
</xsl:stylesheet>
I expect to get only these nodes in fum:
<foo @name="1">a</foo>
<foo @name="1">b</foo>
(As a by-note, xsl:key can't be in the xsl:template......)
Thanks very much!
> This is the XML input:
> <root>
> <foo @name="1">a</foo>
> <foo @name="1">b</foo>
> <foo @name="1">a</foo>
> <foo @name="2">c</foo>
> <foo @name="2">c</foo>
> <foo @name="2">d</foo>
> </root>
I guess
<root>
<foo name="1">a</foo>
<foo name="1">b</foo>
<foo name="1">a</foo>
<foo name="2">c</foo>
<foo name="2">c</foo>
<foo name="2">d</foo>
</root>
is more what you have.
> I expect to get only these nodes in fum:
> <foo @name="1">a</foo>
> <foo @name="1">b</foo>
You simply need to apply the predicate @name = '1' e.g.
/root/foo[@name = '1'][not(. = preceding-sibling::foo[@name = '1'])]
or in that template
<xsl:variable name="fie" select="$in/foo[@name='1']" />
<xsl:variable name="fum" select="$fie[not(. =
preceding-sibling::foo[@name = '1'])]" />
Defining a key is also easy:
<xsl:key name="k1" match="foo[@name = '1']" use="."/>
then you can use Muenchian grouping with that key.
Thanks, that worked!
The thing I missed was to use the predicate [@name = '1'] also after
the preceding-sibling::foo.
Thanks very much, this saved my day!
One follow-up, if I would want the distinct attributes (in this
example distinct @names) as opposed to elements, how would the
preceding-sibling predicate look?
Thanks!
> One follow-up, if I would want the distinct attributes (in this
> example distinct @names) as opposed to elements, how would the
> preceding-sibling predicate look?
/root/foo/@name[not(. = ../preceding-sibling::foo/@name)]
Of course, thanks!
So, a select only gives a selection from a node set, and the original
node set information is still there?
Thanks for any insight.
I am not sure I understand what you are asking but XPath operates on a
tree model and any node selection selects nodes in that tree where the
tree remains intact meaning any parent/child/sibling/ancestor
relationships continue to exist.
That was exactly what I meant: "any parent/child/sibling/ancestor
relationships continue to exist."
Thanks!
<xsl:template name="ed">
<xsl:param name="code" />
<xsl:param name="node"></xsl:param>
<xsl:for-each select="$node/n1:value">
<td><xsl:value-of select="@value"></xsl:value-of></td>
</xsl:for-each>
</xsl:template>
<!--Current Output:-->
<div id="lblvitals">
<table width="100%" class="display" id="vitals">
<thead>
<tr>
<th align="left">Date</th>
<th>14-NOV-99</th>
<th>07-APR-00</th>
</tr>
</thead>
<tbody>
<tr>
<td>Body height</td>
<td>177</td>
<td>177</td>
</tr>
<tr>
<td>Body weight</td>
<td>86</td>
<td>88</td>
</tr>
<tr>
<td>Systolic BP</td>
<td>132</td>
<td>145</td>
</tr>
<tr>
<td>Diastolic BP</td>
<td>86</td>
<td>88</td>
</tr>
<tr>
<td>Body height</td>
<td>177</td>
<td>177</td>
</tr>
<tr>
<td>Body weight</td>
<td>86</td>
<td>88</td>
</tr>
<tr>
<td>Systolic BP</td>
<td>132</td>
<td>145</td>
</tr>
<tr>
<td>Diastolic BP</td>
<td>86</td>
<td>88</td>
</tr>
</tbody>
</table>
</div>
*** Sent via Developersdex http://www.developersdex.com ***