Skip to content
Mike Angstadt edited this page Aug 23, 2018 · 4 revisions

vCard data can be embedded inside an HTML document using the hCard format. hCards loosely adhere to version 3.0 of the vCard specification.

Below is an example of an hCard. The HTML document must contain a <link> element which references the hCard profile. hCards rely heavily on class attributes to identify which parts of the HTML document contain vCard data.

<html>
  <head>
    <link rel="profile" href="http://microformats.org/profile/hcard" />
  </head>
  <body>
    <div class="vcard">
      <h1 class="fn n">
        <span class="prefix">Mr</span>. 
        <span class="given-name">John</span> 
        <span class="family-name">Doe</span>
      </h1>
      
      Email:
      <a class="email" href="mailto:jdoe@example.com">
        <span class="value">jdoe@example.com</span>
        (<span class="type">home</span>)
      </a>

      <p class="note">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec at lacus justo. Phasellus quis nisl eget augue gravida tempor in at ante. Suspendisse suscipit eleifend molestie.
      </p>
    </div>
  </body>
</html>

1 Reading HTML-encoded vCard data

The HCardParser class handles the extraction of vCard data from an HTML document. Unlike most of the other reader classes in ez-vcard, this class is not streaming. The entire HTML DOM must be read into memory before the vCards can be extracted.

1.1 Important methods

readNext()
Parses and returns the next VCard object from the HTML document. The method returns null when no more vCards can be found.

getWarnings()
Returns any problems the parser encountered while parsing the VCard object that was last returned by readNext(). Examples of things that could cause warnings are: unparseable property values (such as malformed date values).

Please see the Javadocs for a complete listing of all the methods.

1.2 Example

The example below outputs the names and birthdays of each hCard found on a company's "staff" page.

URL url = new URL("http://company.com/staff");
HCardParser parser = new HCardParser(url);
try {
  VCard vcard;
  DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
  while ((vcard = parser.readNext()) != null) {
    FormattedName fn = vcard.getFormattedName();
    String name = (fn == null) ? null : fn.getValue();

    Birthday bday = vcard.getBirthday();
    Date date = (bday == null) ? null : bday.getDate();
    String birthday = (date == null) ? null : df.format(date);

    System.out.println(name + " " + birthday);
  }
} finally {
  parser.close();
}

1.3 A note about unparseable property values

If a property's value cannot be parsed (for example, due to a malformed date value), the property is treated as an extended property and a warning is logged. The extended property's value will contain the property's entire HTML element in string form. The code below demonstrates this:

String html =
"<html>" +
  "<head>" +
    "<link rel=\"profile\" href=\"http://microformats.org/profile/hcard\" />" +
  "</head>" +
  "<body>" +
    "<div class=\"vcard\">" +
      "Last modified: <span class=\"rev\">I don't know, like, 2 days ago?</span>" +
    "</div>" +
  "</body>" +
"</html>";

HCardParser parser = new HCardParser(html);
VCard vcard = parser.readNext();
parser.close();

List<String> warnings = parser.getWarnings();
System.out.println("Warnings: " + warnings);

System.out.println("REV property: " + vcard.getRevision());

RawProperty prop = vcard.getExtendedProperty("REV");
System.out.println("Extended property: " + prop.getValue());

The above code produces the following output:

Warnings: [rev property: Property value could not be parsed.  It will be saved as an extended property instead.
  Reason: Could not parse date string.
  HTML: <span class="rev">I don't know, like, 2 days ago?</span>]
REV property: null
Extended property: <span class="rev">I don't know, like, 2 days ago?</span>

1.4 Dependency

If your application does not require hCard parsing functionality, you can exclude the "jsoup" dependency from your build.

<dependency>
  <groupId>com.googlecode.ez-vcard</groupId>
  <artifactId>ez-vcard</artifactId>
  <version>...</version>
  <exclusions>
    <!-- hCard parsing not needed -->
    <exclusion>
      <groupId>org.jsoup</groupId>
      <artifactId>jsoup</artifactId>
    </exclusion>
  </exclusions>
</dependency>

2 Writing HTML-encoded vCard data

hCards are very tightly intertwined with the HTML code of a webpage. Due to this fact, it's difficult to develop a general purpose hCard "writer" that can be used for any given webpage. The HCardPage class creates an HTML page which serves as an example of what a vCard looks like when embedded in HTML. Feel free to use its Freemarker template file as a starting point for learning how to embed a vCard inside an HTML document.

2.1 Important methods

add()
Adds a VCard to the HTML page.

write()
Creates an HTML page that contains the contents of the VCards that were passed into the add() method.

Please see the Javadocs for a complete listing of all the methods.

2.2 Example

The example below writes a list of VCard objects to an HTML file.

List<VCard> vcards = ...
HCardPage page = new HCardPage();
for (VCard vcard : vcards) {
  page.add(vcard);
}

File file = new File("vcards.html");
page.write(file);

2.3 Dependency

If your application does not require the use of the HCardPage class, you can exclude the "freemarker" dependency from your build.

<dependency>
  <groupId>com.googlecode.ez-vcard</groupId>
  <artifactId>ez-vcard</artifactId>
  <version>...</version>
  <exclusions>
    <!-- hCard writing not needed -->
    <exclusion>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
    </exclusion>
  </exclusions>
</dependency>