xsl-list
[Top] [All Lists]

RE: [xsl] many-to-many

2007-01-29 12:23:51


-----Original Message-----
From: Ronan Klyne [mailto:ronan(_dot_)klyne(_at_)groupbc(_dot_)com]
Sent: Monday, January 29, 2007 5:04 AM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] many-to-many


Brown, William S wrote:
Esteemed experts, 
There are a number of examples out there on the net of 
modelling 'many-to-many' relationship in XML.
A recent one is 

http://en.wikibooks.org/wiki/XML:_Managing_Data_Exchange/The_m
any-to-many_relationship
and it is helpful, as far is it goes.
However, Kevin Williams points out in
http://www-128.ibm.com/developerworks/xml/library/x-xdm2m.html
that the usual understanding of the 'many-to-many' 
relationship is that it is a two-way street.

That is, to use an example from the first document, I can 
structure data about movies and actors such that each actor's 
info is represented only once in the XML but pulled out 
repeatedly as I generate a list of movies and the many actors 
that appeared in each; same actors appear in multiple movies.
Or, to use the classic example, I can represent details for 
each part only once, but re-use it as I generate invoices, 
each of which contains many of the same parts.
Each of the above articles suggests an ID/IDREF approach 
for doing this.
However, Williams notes that in relational databases it is 
simple to run the query in reverse, i.e., list the movies 
that each actor has appeared in, or list the invoices on 
which each part appears. Since the ID/IDREF is treated as 
unidirectional, he suggests a double IDREF structure - paired 
pointers pointing in opposite directions.
Which brings me to my question - 
has anyone seen any sample xml/xsl that actually 
demonstrated running the query in forward and reverse. 
Everything I've seen uses ID/IDREF and xsl:key in one 
direction and calls that a 'many-to-many' structure. But I'm 
not clever enough to navigate back upstream (William implies 
it can't be done) or to implement the XSL for the dual ID/IDREF.
The first (wiki) article contains sample xml and xsl for 
anyone who wants to investigate the issue.
I hope you find this diverting (or at least can show me how 
to do it LOL).

Best,

William S. Brown              wsbrown(_at_)bnl(_dot_)gov
Systems Engineering and Safety Analysis Group
Brookhaven National Laboratory 
Building 130                 TEL 631 344 7230
Upton, NY 11973-5000         FAX 631 344 4900


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



Hi William,

I read the many-to-many problem as two one-to-many problems, 
one in each
direction, for which keys are a good solution.
As far as I know, it is not possible to use a key in reverse, so two
keys must be used; one for each direction.

I include an example involving parts and invoices. Is this the kind of
thing you had in mind?

      # r

----- Input data:
<doc>
  <invoices>
    <invoice id="i1">
      <part id="1"/>
      <part id="2"/>
    </invoice>
    <invoice id="i2">
      <part id="5"/>
      <part id="2"/>
    </invoice>
    <invoice id="i3">
      <part id="5"/>
      <part id="3"/>
    </invoice>
    <invoice id="i4">
      <part id="5"/>
      <part id="2"/>
    </invoice>
    <invoice id="i5">
      <part id="3"/>
      <part id="4"/>
    </invoice>
  </invoices>
  <parts>
    <part name="part1" id="1"/>
    <part name="part2" id="2"/>
    <part name="part3" id="3"/>
    <part name="part4" id="4"/>
  </parts>
</doc>

----- Stylesheet:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:output method="html" indent="no" encoding="ISO-8859-1"/>

<xsl:key name="p-i" match="/doc/invoices/invoice" use="part/@id"/>
<xsl:key name="i-p" match="/doc/invoices/invoice/part" use="../@id"/>

<xsl:template match="invoice">
  <h3>invoice <xsl:value-of select="@id"/> contains:</h3>
  <xsl:for-each select="key('i-p', @id)">
    part <xsl:value-of select="@id"/>
  </xsl:for-each>
</xsl:template>

<xsl:template match="part">
  <h3>part <xsl:value-of select="@id"/> was part of invoices:</h3>

  <xsl:for-each select="key('p-i', @id)">
    <xsl:value-of select="@id"/>
  </xsl:for-each>
</xsl:template>

<xsl:template match="doc">
  <h2>invoice to parts</h2>
  <xsl:apply-templates select="invoices/*"/>
  <h2>part to invoices</h2>
  <xsl:apply-templates select="parts/*"/>
</xsl:template>

</xsl:stylesheet>
----- End.


-- 
Ronan Klyne
Business Collaborator Developer
Tel: +44 (0)870 163 2555
ronan(_dot_)klyne(_at_)groupbc(_dot_)com
www.groupbc.com

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>