Skip to content
Michael Angstadt edited this page Jul 24, 2020 · 5 revisions

vCard data can be encoded in XML using the xCard format. The xCard specification is defined in RFC 6351. xCards only adhere to version 4.0 of the vCard specification. They do not support versions 2.1 or 3.0.

Below is an example of a xCard document.

<vcards xmlns="urn:ietf:params:xml:ns:vcard-4.0">
  <vcard>
    <n>
      <surname>Doe</surname>
      <given>John</given>
      <prefix>Mr</prefix>
    </n>
    <fn>
      <text>Mr. John Doe</text>
    </fn>
    <group name="group1">
      <email>
        <parameters>
          <type><text>home</text></type>
        </parameters>
        <text>jdoe@example.com</text>
      </email>
    </group>
    <note>
      <text>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.</text>
    </note>
  </vcard>
</vcards>

1 Reading XML-encoded vCard data

The XCardReader class handles the parsing of XML-encoded vCard data. The data is read in a streaming fashion, meaning it parses the data as it is read off the wire. This results in a smaller memory footprint than other approaches.

1.1.1 Important methods

readNext()
Parses and returns the next VCard object in the data stream. The method returns null when the end of stream has been reached.

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).

close()
As with all I/O operations, it's important to call the close() method when you are done with the XCardReader object in order to properly close the input stream.

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

1.1.2 Example

The example below outputs the names and birthdays of each vCard in the XML data stream.

File file = new File("vcards.xml");
XCardReader reader = new XCardReader(file);
try {
  VCard vcard;
  DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
  while ((vcard = reader.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 {
  reader.close();
}

Alternatively, the XCardDocument class can be used to read XML-encoded vCard data. This class is essentially a wrapper for a org.w3c.dom.Document object, providing methods that read and write VCard objects from/to the DOM tree.

1.2.1 Important methods

getVCards()
Parses all VCard objects out of the DOM tree.

getDocument()
Returns the wrapped Document object, giving you full control over the XML data.

1.2.2 Example

The example below reads XML-encoded vCard data from the Internet and outputs the names and birthdays of each vCard in the DOM.

InputStream in = new URL("http://example.com/vcards.xml").openStream();
XCardDocument document;
try {
  document = new XCardDocument(in);
} finally {
  in.close();
}

List<VCard> vcards = document.getVCards();
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
for (VCard vcard : vcards) {
  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);
}

1.3 A note about unparseable property values

If a property's value cannot be parsed, or if the property's XML element does not have the correct child elements, the property is parsed as an Xml property and a warning is logged. Xml properties store the raw XML of the property that could not be parsed. The code below demonstrates this:

String xml =
"<vcards xmlns=\"urn:ietf:params:xml:ns:vcard-4.0\">" + 
  "<vcard>" +
    "<rev>" +
      "<timestamp>I don't know, like, 2 days ago?</timestamp>" +
    "</rev>" +
  "</vcard>" +
"</vcards>";
XCardReader reader = new XCardReader(xml);
VCard vcard = reader.readNext();
reader.close();

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

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

Xml prop = vcard.getXmls().get(0);
System.out.println("XML property: " + XmlUtils.toString(prop.getValue()));

The above code produces the following output:

Warnings: [rev property: Property value could not be parsed.  It will be saved as a XML property instead.
  Reason: Could not parse date string.
  XML: <?xml version="1.0" encoding="UTF-8"?><rev xmlns="urn:ietf:params:xml:ns:vcard-4.0"><timestamp>I don't know, like, 2 days ago?</timestamp></rev>]
REV property: null
XML property: <?xml version="1.0" encoding="UTF-8"?><rev xmlns="urn:ietf:params:xml:ns:vcard-4.0"><timestamp>I don't know, like, 2 days ago?</timestamp></rev>

2 Writing XML-encoded vCard data

The XCardWriter class handles the serialization of XML-encoded vCard data.

2.1.1 Important methods

write()
Writes the contents of an VCard object to the data stream.

close()
As with all I/O operations, it's important to call the close() method when you are done with the XCardWriter object in order to properly close the output stream. It's especially important for XCardWriter because it must write the proper XML closing tags to properly close the XML document.

2.1.2 Example

The example below writes a list of VCard objects to an XML file. The output will be pretty-printed, using an indentation string of 2 spaces.

List<VCard> vcards = ...
File file = new File("vcards.xml");
XCardWriter writer = new XCardWriter(file, 2);
try {
  for (VCard vcard : vcards) {
    writer.write(vcard);
  }
} finally {
  writer.close();
}

Alternatively, the XCardDocument class can be used to write XML-encoded vCard data. This class is essentially a wrapper for a org.w3c.dom.Document object, providing methods that read and write VCard objects from/to the DOM tree.

2.2.1 Important methods

addVCard()
Adds the contents of an VCard object to the XML DOM tree.

getDocument()
Returns the wrapped Document object, giving you full control over the XML data.

write()
Outputs the XML DOM tree to a string or output stream. This method is overloaded to allow you to customize the write process (for example, by specifying the number of indentation spaces to use to pretty-print the XML).

2.2.2 Example

The example below writes a list of VCard objects to an XML file. The output will be pretty-printed, using an indentation string of 2 spaces.

List<VCard> vcards = ...
XCardDocument document = new XCardDocument();
for (VCard vcard : vcards) {
  document.addVCard(vcard);
}

File file = new File("vcards.xml");
document.write(file, 2);