Selecting a set of nodes

J

jdhcards

Hello,

I've been banging my head against a problem all day without a solution,
and I'm hoping you all can help. I've got a piece of XML that defines a
set of elements in a flat list. Each of these elements has an attribute
"Id" which has a unique value. Some of these elements have a
parent-child relationship, specified with a "ResultId" attribute in one
of the child nodes.

<element id=1>
<child resultid=2/>
<child resultid=3/>
</element>
<element id=2>
</element>
<element id=3>
</element>
<element id=4>

I'm trying to filter the list of elements down to only the parent
elements. My approach has been to create a list of "child ids" and
throw out an element that have an id within that set of "child ids". In
the example above, I'd keep element 1&4, but through away 2 & 3.

I'm having trouble comparing the two node sets. Can anyone offer an
approach or the XSL syntax I'll need to get my approach done?

XSL to select child id's:

<xsl:variable name="subJobResultId"
select="ResultInfo/TaskDetails/*/TaskList/Task/TaskInformation/Task[@RunJobIdResultId
!= '']"/>
 
J

Joe Kesselman

> <child resultid=2/>
> <child resultid=3/>
> </element>
....etcetera.

That isn't an XML document. Attribute values must be quoted, and there
must be a single root element. But we'll assume your actual data is
better formed, for the sake of argument.
> XSL to select child id's:
> <xsl:variable name="subJobResultId"
> select="ResultInfo/TaskDetails/*/TaskList/Task
> /TaskInformation/Task[@RunJobIdResultId!= '']"/>

That really doesn't help us; it doesn't correspond to your sketch
and it introduces a whole bunch of complexities which would tend to
obscure the answer. So I'm not going to make any attempt to write
something that would work against your real data. I'll discuss it in
terms of the sketch, and leave it for you to apply appropriately.
> I'm trying to filter the list of elements down to only the parent
> elements.

And you aren't willing to take the obvious test that only parents will
contain a <child>? "pathToElements/element[child]" would do that quickly
and easily, where pathToElements is whatever path is needed to find the
<element>s.

If you insist on searching for matching values: What you want is those
<element>s which have a child/@resultid whose value matches the @id of
some other <element>. That's simple enough:

pathToElements/element[child/@resultid = ../element/@id]

I'm assuming all <element>s are children of the same parent node; if
not, you may need to replace .. with something more complicated.

This works because testing equality between nodesets returns true if any
node in the first set has the same value as any node in the second set.
(Good example of how to make XPath/XSLT do all the work for you,
actually; no explicit loops, just a flat statement of what you're
looking for.)


By the way:

1) Using examples with names like <element> and <child> makes discussing
this much more difficult than it should be, since we have to distinguish
between the element named element and the logical concept of an element.
PLEASE avoid doing so in the future.

2) If your task permits it, you might want to consider getting rid of
this whole ID/IDREF linkage design and just use XML's own parent/child
hierarchy, nesting elements within each other rather than doing lookups
by name. Of course that isn't always appropriate; sometimes data is
linked multiple ways or there are other constraints that force this
approach... but I've lost count of how many cases I've seen where a
simple change in data structure tremendously simplified the whole
application.

3) If you're using DTDs or schemas, I presume you're declaring id (or
its equivalent) as being of type ID, and resultid (or its equivalent) as
being of type IDREF. That will tell the validator to check that no two
ids have the same value, and that all resultids have a value that
corresponds to one of the ids -- ie, that a reliable many-to-one
relationship exists.

(If you're using schemas, there are fancier alternatives to ID/IDREF, of
course. "But the idea's the important thing." -- Tom Lehrer)
 

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,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top