#

Jump to Table of Contents

# DataSchema

The DataSchema Utility applies a given schema against data of arbitrary formats, normalizing input such as JSON, XML, or delimited text into a JavaScript object with known properties. The value of the DataSchema Utility is in its ability to translate data from a variety of sources into a consistent format for consumption by components in a predictable manner.

## Getting Started

To include the source files for DataSchema and its dependencies, first load the YUI seed file if you haven't already loaded it.

    <script src="http://yui.yahooapis.com/3.10.3/build/yui/yui-min.js"></script>

Next, create a new YUI instance for your application and populate it with the modules you need by specifying them as arguments to the `YUI().use()` method. YUI will automatically load any dependencies required by the modules you specify.

    <script>
    // Create a new YUI instance and populate it with the required modules.
    YUI().use('dataschema', function (Y) {
        // DataSchema is available and ready for use. Add implementation
        // code here.
    });
    </script>

For more information on creating YUI instances and on the `use()` method, see the documentation for the YUI Global Object.

## Using the DataSchema

This section describes how to use the DataSchema in further detail.

### DataSchema basics

DataSchema classes are standalone static utilities that accept data input plus a schema definition and return a JavaScript object with the following properties:

Property | Type | Description
--- | --- | ---
`results` | Array | An array of data.
`meta` | Object | Arbitrary data values filtered from the input data.

Note that the schema you define will depend on which subclass of DataSchema is being used.

#### DataSchema.Array

Use DataSchema.Array when working with JavaScript arrays. These arrays may contain JavaScript objects, other arrays, or primitive values.

    // A sample array of objects
    [
        {make:"Chevrolet",model:"Bel Air",year:1957},
        {make:"Dodge",model:"Dart",year:1964},
        {make:"Ford",model:"Mustang",year:1968}
    ];

    // A sample array of arrays
    [
        ["Chevrolet", "Bel Air", 1957],
        ["Dodge", "Dart", 1964],
        ["Ford", "Mustang", 1968]
    ];

    // A sample array of primitives
    [
        "1957 Chevrolet Bel Air", "1964 Dodge Dart", "1968 Ford Mustang"
    ];

Define a schema with the following properties for your array data:

Property | Type | Description
--- | --- | ---
`resultFields` | Array | Keys to assign to the values contained in the array.

    var mySchema = {
            resultFields: [{key:"make"}, {key:"model"}, {key:"year"}]
    };

    // Returns an object with the properties "results" and "meta"
    var myOutput = Y.DataSchema.Array.apply(mySchema, myData);

#### DataSchema.JSON

Use DataSchema.JSON when working with JavaScript objects or JSON data. Typically, your data will hold meta values as well as an internal array of tabular data.

    // Sample JSON data
    {
        "profile":{
            "current":160,
            "target":150
        },
        "program": [
            {
                "category":"exercise",
                "weekly schedule":[
                    {"day":"sunday", "activity":"swimming"},
                    {"day":"monday", "activity":"running"},
                    {"day":"tuesday", "activity":"biking"},
                    {"day":"wednesday", "activity":"running"},
                    {"day":"thursday", "activity":"swimming"},
                    {"day":"friday", "activity":"running"},
                    {"day":"saturday", "activity":"golf"}
                ]
            }
        ]
    };

Locators are string values in your schema that use dot notation or bracket syntax to point to data values within the object. Define a schema with the following properties for your object data:

Property | Type | Description
--- | --- | ---
`metaFields` | Object | Key/locator pairs that point to arbitrary data values.
`resultListLocator` | String | Locator to an internal array of tabular data.
`resultFields` | Array | Keys to assign to the values contained in the array.

    var mySchema = {
        metaFields: {current:"profile.current", target:"profile.target"},
        resultListLocator: "program[0]['weekly schedule']",
        resultFields: [{key:"day"}, {key:"activity"}]
    };

    // Returns an object with the properties "results" and "meta"
    var myOutput = Y.DataSchema.JSON.apply(mySchema, myData);

#### DataSchema.XML

Note: XML parsing currently has known issues on the Android WebKit browser.

Use DataSchema.XML when working with XML data. As with JSON data, your XML data may hold meta values as well as an internal node list of tabular data.

    // Sample XML data
    <Response>
        <Session>542235629</Session>
        <Tracks start="1" count="10" total="98" errorCount="0"
            defaultSort="popularity+" description="Top 100 Tracks"
            name="Top 100 Tracks">
            <Track id="59672468" rating="-1" title="I Kissed A Girl">
                <Artist id="30326214" rating="-1">Katy Perry</Artist>
                <ItemInfo><ChartPosition last="26" this="1"/></ItemInfo>
            </Track>
            <Track id="47973564" rating="-1" title="Shake It">
                <Artist id="45575683" rating="-1">Metro Station</Artist>
                <ItemInfo><ChartPosition last="27" this="2"/></ItemInfo>
            </Track>
            <Track id="52207363" rating="-1" title="Bleeding Love">
                <Artist id="37956508" rating="-1">Leona Lewis</Artist>
                <ItemInfo><ChartPosition last="28" this="3"/></ItemInfo>
            </Track>
        </Tracks>
    </Response>

Locators are XPath string values in your schema that point to data values within the XML. Define a schema with the following properties for your XML data:

Property | Type | Description
--- | --- | ---
`metaFields` | Object | Key/locator pairs that point to arbitrary data values.
`resultListLocator` | String | Locator to an internal node list of tabular data.
`resultFields` | Array | Keys to assign to the values contained in the array. Locators may be defined to point to complex nested values or values held in attributes.

    var mySchema = {
        metaFields: {session:"//Session", total:"//Tracks/@total"},
        resultListLocator: "Track", // node name or XPath
        resultFields: [{key:"song", locator:"@title"}, {key:"artist", locator:"Artist"}, {key:"rank", locator:"ItemInfo/ChartPosition/@this"}]
    };

    // Returns an object with the properties "results" and "meta"
    var myOutput = Y.DataSchema.XML.apply(mySchema, myData);

#### DataSchema.Text

Use DataSchema.Text when working with delimited textual data. Typically, your data will not contain meta values.

    // Sample text data
    notebooks, 100, spiral-bound
    pencils, 300, #2 erasers
    pens, 500, blue ink

Define a schema with the following properties for your text data:

Property | Type | Description
--- | --- | ---
`resultDelimiter` | String | Delimiter separating each row of tabular data
`fieldDelimiter` | String | Delimiter separating each column of tabular data
`resultFields` | Array | Keys to assign to the values contained in each field (column).

    var mySchema = {
        resultDelimiter: "\\n",
        fieldDelimiter: ",",
        resultFields: [{key:"product"}, {key:"quantity"}, {key:"detail"}];

    // Returns an object with the properties "results" and "meta"
    var myOutput = Y.DataSchema.Text.apply(mySchema, myData);

### DataSchema as a DataSource plugin

DataSchema plugins integrate DataSource's retrieval functionality with schema-based normalization of the retrieved data for further consumption by another component. There are currently four available DataSource plugins: DataSourceArraySchema, DataSourceJSONSchema, DataSourceXMLSchema, and DataSourceTextSchema.

    myDataSource.plug({fn: Y.Plugin.DataSourceJSONSchema, cfg: {
        schema: {
            resultListLocator: "ResultSet.Result",
            resultFields: ["Title"]
        }
    }});

    // myCallback functions will receive the schema-normalized response object
    myDataSource.sendRequest({
        request: myRequest,
        callback: myCallback
    });

## Known Issues

Known Android issues (bugs 2529621, 2529758, 2529775): XML parsing is currently buggy on the Android WebKit browser.