Why Can’t I Subscribe to an Address Card?

The other day, I was talking to an old friend and doing that annoying ritual where I told her all of the phone numbers and email addresses I had for her, and she told me which ones were out of date and which ones I was missing. And I wondered why there’s not a better way of doing this. Especially when it’s so simple.

For those who don’t know: when you make an appointment to take your car to the garage and the web site allows you to add it to your calendar, or when your doctor emails you a reminder for your upcoming exam that you can click and add to your calendar, you’re downloading an iCalendar file. This is a file format for describing calendar events. All major calendar tools support it. It’s a well-known, widely-supported standard file type.

You can also subscribe to a calendar: your school or community center can publish a calendar of events simply by publishing an iCalendar file on their web site. Then your desktop calendar program can check the calendar’s URL once an hour or whatever, and show you the events.

Now, there’s another file type for contacts, called vCard or VCF. Where iCalendar is for appointments, vCard is for contacts: you can store a person’s name, addresses, job title, phone numbers, web site, and so on and so forth. Tools like Google Contacts allow you to export some or all of your contacts in vCard format because it’s so widely-supported.

Which brings up the obvious question I asked above: why can’t I subscribe to an address card the same way I subscribe to a calendar? My friend could simply have put her iCalendar file on a web site somewhere, and my address book utility could check the URL once a day or so to see whether she changed her phone number or postal address, or added a Discord account or something.

So… why?

There Are Days When I Hate XML

…and days when I really hate XML.

In this case, I have an XML document like

<?xml version="1.0" ?>
<foo xmlns="http://some.org/foo">
  <thing id="first"/>
  <thing id="second"/>
  <thing id="third"/>

and I want to get things out of it with XPath.

But I couldn’t manage to select things exactly, such as the <foo> element at the top. You’d think “/foo” would do it, but it didn’t.

Eventually I found out that the problem is the xmlns=”...” attribute. It looks perfectly normal, saying that if you have <thing> without a prefix (like “<ns:thing>”), then it’s in the “http://some.org/foo” namespace.

However, in XPath, if you specify “ns:thing”, it means “a thing element in whichever namespace the ns prefix corresponds to”. BUT “thing” means “a thing element that’s not in a namespace”.

So how do you specify an element that’s the empty-string namespace, as above? The obvious way would be to select “:thing”, but that doesn’t work. Too simple, I suppose. Maybe that gets confused with CSS pseudo-selectors or something.

No, apparently the thing you need to do is to invent a prefix for the standard elements of the file you’re parsing. That is, add “ns” as another prefix that maps onto “http://some.org/foo” and then select “ns:thing”. There are different ways of doing this, depending which library you’re using to make XPath queries, but still, it seems like a giant pain in the ass.