---
name: "bson_parsing"
section: "3"
platform: "linux"
package: "libbson-doc"
version: "1.23.1-1+deb12u3"
release: "Debian 12 (Bookworm)"
platforms: ["linux"]
url: "https://new.carta.tech/bson_parsing"
---

# bson\_parsing(3)

Parsing and Iterating BSON Documents

## NAME

bson\_parsing - Parsing and Iterating BSON Documents

## PARSING

BSON documents are lazily parsed as necessary. To begin parsing a BSON document, use one of the provided Libbson functions to create a new *bson\_t* from existing data such as *bson\_new\_from\_data()*. This will make a copy of the data so that additional mutations may occur to the BSON document.

**TIP:**

If you only want to parse a BSON document and have no need to mutate it, you may use *bson\_init\_static()* to avoid making a copy of the data.

```
bson_t *b;
b = bson_new_from_data (my_data, my_data_len);
if (!b) {
   fprintf (stderr, "The specified length embedded in <my_data> did not match "
                    "<my_data_len>\n");
   return;
}
bson_destroy (b);
```

Only two checks are performed when creating a new *bson\_t* from an existing buffer. First, the document must begin with the buffer length, matching what was expected by the caller. Second, the document must end with the expected trailing **\\0** byte.

To parse the document further we use a *bson\_iter\_t* to iterate the elements within the document. Let's print all of the field names in the document.

```
bson_t *b;
bson_iter_t iter;
if ((b = bson_new_from_data (my_data, my_data_len))) {
   if (bson_iter_init (&iter, b)) {
      while (bson_iter_next (&iter)) {
         printf ("Found element key: \"%s\"\n", bson_iter_key (&iter));
      }
   }
   bson_destroy (b);
}
```

Converting a document to JSON uses a *bson\_iter\_t* and *bson\_visitor\_t* to iterate all fields of a BSON document recursively and generate a UTF-8 encoded JSON string.

```
bson_t *b;
char *json;
if ((b = bson_new_from_data (my_data, my_data_len))) {
   if ((json = bson_as_canonical_extended_json (b, NULL))) {
      printf ("%s\n", json);
      bson_free (json);
   }
   bson_destroy (b);
}
```

## RECURSING INTO SUB-DOCUMENTS

Libbson provides convenient sub-iterators to dive down into a sub-document or sub-array. Below is an example that will dive into a sub-document named "foo" and print it's field names.

```
bson_iter_t iter;
bson_iter_t child;
char *json;
if (bson_iter_init_find (&iter, doc, "foo") &&
    BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child)) {
   while (bson_iter_next (&child)) {
      printf ("Found sub-key of \"foo\" named \"%s\"\n",
              bson_iter_key (&child));
   }
}
```

## FINDING FIELDS USING DOT NOTATION

Using the *bson\_iter\_recurse()* function exemplified above, *bson\_iter\_find\_descendant()* can find a field for you using the MongoDB style path notation such as "foo.bar.0.baz".

Let's create a document like **{"foo": {"bar": \[{"baz: 1}\]}}** and locate the **"baz"** field.

```
bson_t *b;
bson_iter_t iter;
bson_iter_t baz;
b =
   BCON_NEW ("foo", "{", "bar", "[", "{", "baz", BCON_INT32 (1), "}", "]", "}");
if (bson_iter_init (&iter, b) &&
    bson_iter_find_descendant (&iter, "foo.bar.0.baz", &baz) &&
    BSON_ITER_HOLDS_INT32 (&baz)) {
   printf ("baz = %d\n", bson_iter_int32 (&baz));
}
bson_destroy (b);
```

## VALIDATING A BSON DOCUMENT

If all you want to do is validate that a BSON document is valid, you can use *bson\_validate()*.

```
size_t err_offset;
if (!bson_validate (doc, BSON_VALIDATE_NONE, &err_offset)) {
   fprintf (stderr,
            "The document failed to validate at offset: %u\n",
            (unsigned) err_offset);
}
```

See the *bson\_validate()* documentation for more information and examples.

## AUTHOR

MongoDB, Inc

## COPYRIGHT

2017-present, MongoDB, Inc
