vCard 3.0 validator and parser

Did you know that even the vCards listed in the official RFC are not valid? It clearly says The vCard object MUST contain the FN, N and VERSION types. Still, the example vCards are both clearly missing the N type. As somebody else remarked, releasing a format spec without some reference validator is bound to result in all sorts of invalid implementations.

After searching for a vCard validator without success, I’ve therefore started my own vCard module in Python. It tries to create an object with all the information from a vCard string, and returns what I hope are useful error and warning messages if there’s anything wrong.

Update: Added file validation – Now you can validate files with several vCards from the command line.

Install / upgrade:
sudo pip install --upgrade vcard

Validate vCard files:
vcard *.vcf

Advertisements

28 thoughts on “vCard 3.0 validator and parser

  1. Pingback: HOWTO: Synchronizing vCard address books with Nokia 6300 via Bluetooth on Ubuntu Linux « Paperless

    • I had a look at it before developing this, and as far as I can see from the documentation it supports a much smaller subset of vCards. I remain open to convincing though, especially since I’ve yet to find a generator that creates valid vCards.

  2. I just installed this to test out the vcard I was programmatically generating, and I get the error message:

    “Could not process entire joe-blow.vcf – 214 lines remain”

    Even with the verbose flag, this is all I get. Any chance of getting some more useful info?

    • This means that the file doesn’t contain anything that could be validated – In other words, it contains no vCards. The simplest reason for this is if the line endings are wrong – The standard mandates that each line be terminated with carriage return followed by newline (aka. \r\n or CRLF).

    • Sorry, there’s just way too many interesting projects in the pipeline to promise any such interfaces. But you or anyone you know are of course free to do so – It’s open source.

  3. I also got the “Could not process entire joe-blow.vcf – 214 lines remain” message, except that my file did have carriage returns and linefeeds ending each line (this is simple to achieve with vim, just set fileformat=dos with ‘:set ff=dos’). However, I was still getting the message until I noticed that each of your testcases end with a blank line. So I added the blank line at the end of my file and it worked. Now I am not sure if the blank line is required or whether it is just a quirk of your program.

    • Yes, and thank you for the interest, but I don’t think I’ll be the best (or even the third best) person to do it. First, this project is my first validator, and as such the code is not very good. There’s a lot of duplication, and the validator usually just stops at the first sign of trouble rather than trying to find as many issues as possible in each run (like the excellent W3C validator). Second, vCard 3 is serving me well (warts included), and I don’t think there’s much benefit in moving to Yet Another Standard (but I’m open to arguments). And last, the curse of any developer, there are just too many interesting things to work on!

      tl;dr I probably won’t, but anyone is welcome to.

  4. Hi,

    i have a v3.0 but become always this msg:

    > vcard -v ./3.vcf
    Could not process entire ./3.vcf – 12 lines remain

    I have checked the file for CRLF and a free line at the end.
    All looks good.

    the verbose switch brings no more infos.

    here an example vcf, where i become an error.
    Whats wrong here?

    3.vcf:
    BEGIN:VCARD
    VERSION:3.0
    PRODID:-//Apple Inc.//Mac OS X 10.8.4//EN
    N:Doe;John;;;
    FN:John Doe
    ORG:Stiftung Soundso für Soundso e. V.;
    TEL;type=WORK;type=VOICE;type=pref:+49 (0 89) 87 65 43 – 21
    TEL;type=WORK;type=FAX:+49 (0 89) 12 34 56 78
    ADR;type=WORK;type=pref:;;Hauptstr. 123;München;;;Deutschland
    REV:2013-06-26T10:37:31Z
    UID:ed6aa1aa-2aaa-47aa-a4aa-95aac16785aa
    END:VCARD

    Best regards,
    Daniel.

  5. I’m sorry, but this wrong. Here is the formal grammar that defines what a vCard is:
    vcard = [group “.”] “BEGIN” “:” “VCARD” 1*CRLF
    1*(contentline)
    ;A vCard object MUST include the VERSION, FN and N types.
    [group “.”] “END” “:” “VCARD” 1*CRLF
    It allows for blank lines after the END:VCARD line, but does not require them. Look at the examples from the CardDAV RFC for verification.

  6. I’m glad that I found this. I’m (perhaps stupidly) trying to teach myself Python through creating an actual application. I’ve decided to use vcards as the record format for people, but haven’t been able to find much. VObjects seems to be more calendar focused.

    I’ve played around for a couple of years with Python, and have just decided to sink or swim with 3.4. It strikes me that the model for a vcard is pretty straightforward, so I might as well define it myself according to standard.

    I’ll read through what you have and hopefully that way, I’ll have a decent model structure as well as a validation tool.

    Thanks for sharing this.

  7. Having a VCF-file starting with a UTF8 BOM causes the validator to reject the entire file.

    The current RFC for vcards (6350) states that the charset for vcard is utf-8. Not a complaint, just an observation. I have not found any other useful tool for validating vcards.

  8. You said “vCard 3 is not UTF-8.”
    https://tools.ietf.org/html/rfc6350
    3.1. Charset

    The charset (see [RFC3536] for internationalization terminology) for
    vCard is UTF-8 as defined in [RFC3629]. There is no way to override
    this. It is invalid to specify a value other than “UTF-8” in the
    “charset” MIME parameter (see Section 10.1).

    It is saying the charset is UTF-8 period.

    My testing is showing that if I include non asci characters (>127) in any of the fields
    some applications reading them show it as an invalid vcard.

    If I add a charset on EVERY field that has a UTF-8 character (>127) it seems to work.

    1) You say vcard 3.0 is not utf-8
    2) the rfc says they are only utf-8
    3) testing shows I need a charset for all data that isn’t asci.

    For example
    FN;CHAR SET=UTF-8:MarkÜ

    Help!

    • My mistake. I am referring the vCard 4.0 specs.
      The 4.0 specs say 4.0 is always UTF-8. (RFC3629)

      1) For verson 3.0 vCards,
      should I add a charset as part of the header or add it to every line with a char >127
      or both?

      2) what is the correct header for 3.0 vCards with international (UTF-8) characters?
      text/directory; charset=”utf-8″;

      Thanks.

  9. I came across this site when looking for a discussion group about vCards, and at the risk of going off-topic, I would ask the following question:
    What happens when John Doe gets married?
    FN: Mr & Mrs John and Jane Doe ? (Mr & Mrs John Doe is preferable)
    N:Doe;John; and Jane;Mr & Mrs;; ? (using wife’s given name as “Additional Name”
    I also want to find some way of extracting LABEL data to print my address labels in (preferably) a Linux environment

    • Graeme, vCards are meant to be one per person, so you would have two vCards for a couple. You can use a custom X-WHATEVER property to for example refer to people’s significant other; X-SPOUSE is a common such property.

      Questions about manipulating vCard files in Linux are probably better directed to Unix & Linux Stack Exchange.

  10. Thanks for a prompt and informative reply. I had hoped to use vCards as a common base to maintain contacts in Linux, Android and Windows environments, including the usual Christmas card label print, but clearly a bit of programmatic intervention would be required. I presume X-SPOUSE and X-PARTNER would cover all the usual pairings!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s