Extending HealthVault Data Types

Applications frequently have to represent something that is not encapsulated by the data structure of the HealthVault data types. Out of the box, HealthVault provides a mechanism by which a data type can be extended.

Every application can choose to write XML information in the extension tag within the common data section of a data type. It is recommended that applications distinguish their extension elements by using a unique source attribute on the extension element.

In our example, let’s assume we are extending the daily dietary intake type to add information on alcohol consumption.

Creating a Type Extension

We would like to track the amount of alcohol consumed in a simple element called “alcoholic-drinks”. To simplify things further, we assume this element represents the number of alcoholic drinks including wine, beer, cocktails etc., and is normalized to mean average alcohol per unit.

The first step is to write an alcoholic-drinks XML element within the extension tag using a unique source (_appDailyAlcoholExtensionName) in the extension element. Lines 12 in Example 4-9 show how one can do it in the .NET SDK.

Example 4-9. Creating a type extension

    protected void Submit_Daily_Diet_Click(object sender, System.EventArgs e)
    {
        //Post Diet
        DietaryDailyIntake diet = new DietaryDailyIntake();
        int totalCarbs;
        int.TryParse(Txt_DailyDietCarbs.Text, out totalCarbs);
        diet.TotalCarbohydrates.Kilograms = totalCarbs * 1000;
        diet.CommonData.Note = Txt_DailyDietNote.Text;

        //Adding extension data
        string drinks = Txt_DailyDietAlcohol.Text;
        HealthRecordItemExtension extension =
            new HealthRecordItemExtension(_appDailyAlcoholExtensionName);
        diet.CommonData.Extensions.Add(extension);
        XPathNavigator navigator = extension.ExtensionData.CreateNavigator(); 1
        navigator.InnerXml = @"<extension source=""" + _appDailyAlcoholExtensionName + @""">
                <alcoholic-drinks>" + drinks + "</alcoholic-drinks>"; 2

        PersonInfo.SelectedRecord.NewItem(diet);
    }

Consuming a Type Extension

The second step is to read information from the extension. In our application, the user enters alcoholic drink information through a text box associated with the Daily Dietary intake section, as shown in Figure 4-9.

Input section for Daily Dietary Intake

Figure 4-9. Input section for Daily Dietary Intake

Lines 13 in Example 4-10 show how one can read <alcoholic-drinks> XML. To parse this information we use XPath, and in the data type document, the element of interest resides at extension/alcoholic-drinks. Using the .NET XPathNavigator class, we select a single note signifying this value (Lines 12). Line 4 fetches the note associated with this instance of daily dietary intake. The user can potentially input clarifying information—for example, “drank 3 tequila shots”—in this element.

Example 4-10. Consuming a type extension

    private void DisplayDailyDiet(List<DietaryDailyIntake> dailydiets)
    {
        DataTable dailydiet = new DataTable("DailyDiets");
        dailydiet.Columns.Add(new DataColumn("Date"));
        dailydiet.Columns.Add(new DataColumn("Carbs (in gm)"));
        dailydiet.Columns.Add(new DataColumn("Alcohol (#drinks)"));
        dailydiet.Columns.Add(new DataColumn("Note"));
        foreach (DietaryDailyIntake e in dailydiets)
        {
            DataRow row = dailydiet.NewRow();
            row["Date"] = e.EffectiveDate.ToShortDateString().ToString();
            row["Carbs (in gm)"] = e.ToString();
            foreach(HealthRecordItemExtension extension in e.CommonData.Extensions)
            {
                if (extension.Source == _appDailyAlcoholExtensionName)
                {
                    XPathNavigator navigator = extension.ExtensionData.CreateNavigator();
                    XPathNavigator alcoholicDrinksNavigator = 1
                        navigator.SelectSingleNode("extension/alcoholic-drinks"); 2
                    if (alcoholicDrinksNavigator != null) 3
                    {
                        row["Alcohol (#drinks)"] = alcoholicDrinksNavigator.Value;
                    }
                }
            }
            row["Note"] = e.CommonData.Note; 4
            dailydiet.Rows.Add(row);
        }
        DailyDietView.DataSource = dailydiet;
        DailyDietView.DataBind();
    }

Applications may choose to combine and formalize the two steps just shown and create an extension class, which then could be registered with HealthVault SDK so that every time the extend type is accessed by the application, the appropriate extension properties are available.

Get Enabling Programmable Self with HealthVault now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.