[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Hierarchy - Part 2 - How we think our data would look in ATOM



What I have tried to do in this e-mail is take an existing Web3S example data structure and translate it into ATOM. I tried my best to create something that was reasonable. I am sure there are better ways of handling this than what I have done, I just don't know what they are. So I'm coming to the group and asking for help. How can we both meet our addressability requirements and still be ATOM compliant?

Below is an example data structure for an address book encoded following Web3S. To be clear, I am not proposing Web3S to this group. I am just using this as an example to illustrate the data and capabilities we are trying to achieve.

<LiveContacts xmlns="Web3SBase:com.live.livecontacts" xmlns:Web3S="Web3S:">
   <Owner>
      <WindowsLiveID>demowld@xxxxxxxxxxx</WindowsLiveID>
   </Owner>
   <Contacts>
      <Contact>
         <Web3S:ID>69257004-966e-4ee1-8552-5564f17c7cad</Web3S:ID>
         <AutoUpdateEnabled>false</AutoUpdateEnabled>
         <Profiles>
            <Personal>
               <FirstName>My</FirstName>
               <LastName>Friend</LastName>
            </Personal>
         </Profiles>
         <Emails>
            <Email>
               <Web3S:ID>1</Web3S:ID>
               <EmailType>Personal</EmailType>
               <Address>myfriend@xxxxxxxxxxx</Address>
               <IsIMEnabled>false</IsIMEnabled>
               <IsDefault>true</IsDefault>
            </Email>
         </Emails>
         <Locations>
            <Location>
               <Web3S:ID>1</Web3S:ID>
               <LocationType>Personal</LocationType>
               <StreetLine>456 Minor Street</StreetLine>
               <PrimaryCity>Redmond</PrimaryCity>
               <Subdivision>WA</Subdivision>
               <PostalCode>98052</PostalCode>
               <CountryRegion>USA</CountryRegion>
               <IsDefault>false</IsDefault>
            </Location>
         </Locations>
      </Contact>
   </Contacts>
</LiveContacts>

One of the most important aspects of this structure is how to create URLs from it. A caller would need to know the structure's root out of band. Let's say that root is http://somewhere.live.com/somerootfeed/. In that case the root of this data structure would be URL addressable using http://somewhere.live.com/somerootfeed/com.live.livecontacts.LiveContacts. However anyone with a copy of this structure can reference any part of it at will. For example, if we wanted to address the PostalCode element inside of Location the URL would be http://somewhere.live.com/somerootfeed/com.live.livecontacts.LiveContacts/com.live.livecontacts.Contacts/com.live.livecontacts.Contact(69257004-966e-4ee1-8552-5564f17c7cad)/com.live.livecontacts.Locations/com.live.livecontacts.Location(1)/com.live.livecontacts.PostalCode.

Yes, the URL is horrendous and we are discussing ways to compress it (see question 5.7 in http://dev.live.com/livedata/web3sFAQ.htm).

But the consequence of this design is that anyone can GET/PUT/POST/DELETE any element at any level in the data structure by knowing nothing other than the structure of the data. It's kind of a poor man's XPATH. It also allows us to meet the retrieval/update addressability requirements I explained in part 1 of this e-mail pair.

In representing this data structure in ATOM we wanted to keep the same addressability but if we really took this issue all the way to the extreme then every single element in the previous structured would have to be placed in its own entry. That just seemed to be taking things too far. So the rule I used in encoding the data into Atom is that any element that contains text will be treated as a foreign element of its parent. However any element that contains other elements would be modeled as a feed or an entry depending on context. I assume that we would have to come out with some kind of extension to ATOM that would make it possible to address foreign elements directly so we could keep the same level of addressability we currently have.

Another benefit of the previous data structure is that all the data is completely self describing. In the case of ATOM, feed/entry don't describe our actual syntax or semantics. To solve this problem we use category. We are required to use the term attribute but we really don't have a good use for it so we just leave it blank. Instead we use the scheme attribute to encode a URL that identifies the syntax and semantics of the associated entry or feed.

I have discussed how we handled author, title, updated, summary and id in a separate email so I won't repeat that information here.

I also need to ask Mark Nottingham if I used <fh:complete/> correctly. While complete can be put into a feed it isn't clear to me if it automatically applies to all of its children hierarchically. Also if someone retrieves a child separately wouldn't they need the fh:complete value to be there anyway? For now we put fh:complete into all of the feed elements.

I created a modified form of the ATOM RelaxNG schema so it should (famous last words) properly validate the content elements that contain atom feeds. I then ran that modified RelaxNG schema using JING against the example I give below. I realize that the schema can never be complete (e.g. one must read the spec) but I hope this at least will catch any gratuitous errors.

So, here is the result. Again, I'm not claiming this is the best, perfect or even right way to handle our data needs in atom. This is just the result of me trying to come up with something that seemed to keep with both the syntax and spirit of ATOM as well as meet most of our needs. Comments are actively solicited.

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"; xml:base="http://example.com/joe@xxxxxxxx/LiveContacts";
         xmlns:L="http://live.com/LiveContacts"; xmlns:fh="http://purl.org/syndication/history/1.0";>
   <title/><author><name>a</name></author><updated>0001-01-01T01:00:00</updated><fh:complete/>
   <id>http://somewhere.live.com/somerootfeed/LiveContacts</id>
   <link rel="edit" type="application/atom+xml" href=""/>
   <category term="" scheme="Web3SBase:com.live.livecontacts.livecontacts"/>
   <entry>
      <title/><updated>0001-01-01T01:00:00</updated>
      <id>http://somewhere.live.com/somerootfeed/LiveContacts/Owner</id>
      <link rel="edit" type="application/atom+xml" href="/LiveContacts/Owner"/>
      <category term="" scheme="Web3SBase:com.live.livecontacts.owner"/>
      <L:WindowsLiveid>demowld@xxxxxxxxxxx</L:WindowsLiveid>
   </entry>
   <entry>
      <title/><updated>0001-01-01T01:00:00</updated>
      <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts</id>
      <link rel="edit" type="application/atom+xml" href="/LiveContacts/Contacts"/>
      <category term="" scheme="Web3SBase:com.live.livecontacts.Contacts"/>
      <content type="application/atom+xml">
         <feed>
            <title/><author><name>a</name></author><updated>0001-01-01T01:00:00</updated><fh:complete/>
            <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts?itemsContainer</id>
            <entry>
               <title/><updated>0001-01-01T01:00:00</updated>
               <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)</id>
               <link rel="edit" type="application/atom+xml" href="/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)"/>
               <category term="" scheme="Web3SBase:com.live.livecontacts.Contact"/>
               <L:AutoUpdateEnabled>false</L:AutoUpdateEnabled>
               <content type="application/atom+xml">
                  <feed>
                     <title/><author><name>a</name></author><updated>0001-01-01T01:00:00</updated><fh:complete/>
                     <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)?itemsContainer</id>
                     <entry>
                        <title/><updated>0001-01-01T01:00:00</updated>
                        <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Profiles</id>
                        <link rel="edit" type="application/atom+xml" href="/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Profiles"/>
                        <category term="" scheme="Web3SBase:com.live.livecontacts.Profiles"/>
                        <content type="application/atom+xml">
                           <feed>
                              <title/><author><name>a</name></author><updated>0001-01-01T01:00:00</updated><fh:complete/>
                              <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Profiles?itemsContainer</id>
                              <entry>
                                 <title/><updated>0001-01-01T01:00:00</updated>
                                 <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Profiles/Personal</id>
                                 <link rel="edit" type="application/atom+xml" href="/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Profiles/Personal"/>
                                 <category term="" scheme="Web3SBase:com.live.livecontacts.Personal"/>
                                 <L:FirstName>My</L:FirstName>
                                 <L:LastName>Friend</L:LastName>
                              </entry>
                           </feed>
                        </content>
                     </entry>
                     <entry>
                        <title/><updated>0001-01-01T01:00:00</updated>
                        <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Emails</id>
                        <link rel="edit" type="application/atom+xml" href="/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Emails"/>
                        <category term="" scheme="Web3SBase:com.live.livecontacts.Emails"/>
                        <content type="application/atom+xml">
                           <feed>
                              <title/><author><name>a</name></author><updated>0001-01-01T01:00:00</updated><fh:complete/>
                              <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Emails?itemsContainer</id>
                              <entry>
                                 <title/><updated>0001-01-01T01:00:00</updated>
                                 <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Emails/Email(1)</id>
                                 <link rel="edit" type="application/atom+xml" href="/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Emails/Email(1)"/>
                                 <category term="" scheme="Web3SBase:com.live.livecontacts.Email"/>
                                 <L:EmailType>Personal</L:EmailType>
                                 <L:Address>myfriend@xxxxxxxxxxx</L:Address>
                                 <L:IsIMEnabled>false</L:IsIMEnabled>
                                 <L:IsDefault>true</L:IsDefault>
                              </entry>
                           </feed>
                        </content>
                     </entry>
                     <entry>
                        <title/><updated>0001-01-01T01:00:00</updated>
                        <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Locations</id>
                        <link rel="edit" type="application/atom+xml" href="/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Locations"/>
                        <category term="" scheme="Web3SBase:com.live.livecontacts.Locations"/>
                        <content type="application/atom+xml">
                           <feed>
                              <title/><author><name>a</name></author><updated>0001-01-01T01:00:00</updated><fh:complete/>
                              <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Locations?itemsContainer</id>
                              <entry>
                                 <title/><updated>0001-01-01T01:00:00</updated>
                                 <id>http://somewhere.live.com/somerootfeed/LiveContacts/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Locations/Location(1)</id>
                                 <link rel="edit" type="application/atom+xml" href="/Contacts/Contact(69257004-966e-4ee1-8552-5564f17c7cad)/Locations/Location(1)"/>
                                 <category term="" scheme="Web3SBase:com.live.livecontacts.Location"/>
                                 <L:LocationType>Personal</L:LocationType>
                                 <L:StreetLine>456 Minor Street</L:StreetLine>
                                 <L:PrimaryCity>Redmond</L:PrimaryCity>
                                 <L:Subdivision>WA</L:Subdivision>
                                 <L:PostalCode>98052</L:PostalCode>
                                 <L:CountryRegion>USA</L:CountryRegion>
                                 <L:IsDefault>false</L:IsDefault>
                              </entry>
                           </feed>
                        </content>
                     </entry>
                  </feed>
               </content>
            </entry>
         </feed>
      </content>
   </entry>
</feed>