OPXF 0.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package OPXF --version 0.1.0
                    
NuGet\Install-Package OPXF -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="OPXF" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="OPXF" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="OPXF" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add OPXF --version 0.1.0
                    
#r "nuget: OPXF, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package OPXF@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=OPXF&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=OPXF&version=0.1.0
                    
Install as a Cake Tool

opxf-dotnet

Strongly-typed .NET library for the Open Product Exchange Format (OPXF) — POCOs, System.Text.Json converters, and cross-file conformance validation.

Overview

OPXF is a PIM-agnostic transit format for moving product data from enterprise PIM systems (Akeneo, Inriver, Struct, Pimcore, Bluestone) into downstream consumers (e-commerce platforms, PDF engines, and other channels). This library provides the .NET foundation for working with OPXF payloads.

An OPXF exchange consists of two files:

File Purpose
model.json The Definition Manifest — attribute types, localization rules, value lists, product types, category trees
data.json The Product Payload — products, variants, supporting objects, and assets

Installation

dotnet add package OPXF

Targets .NET 8 and .NET 9.

Usage

Deserialize

using OPXF;

var model = OpxfSerializer.DeserializeModel(File.ReadAllText("model.json"));
var data  = OpxfSerializer.DeserializeData(File.ReadAllText("data.json"));

Validate

using OPXF.Validation;

var validator = new OPXFValidator();
var result = validator.Validate(model, data);

if (!result.IsValid)
{
    foreach (var error in result.Errors)
        Console.WriteLine(error); // [CONF-02] /data/products/0/productTypeId: unknown productTypeId 'apparel'
}

Serialize

string json = OpxfSerializer.SerializeData(data);

Stream-based I/O

For large payloads, use the stream overloads to avoid loading the full JSON into a string:

await using var modelStream = File.OpenRead("model.json");
await using var dataStream  = File.OpenRead("data.json");

var model = await OpxfSerializer.DeserializeModelAsync(modelStream);
var data  = await OpxfSerializer.DeserializeDataAsync(dataStream);

await using var outStream = File.Create("data.out.json");
await OpxfSerializer.SerializeDataAsync(data, outStream);

Work with attribute values

using OPXF.Data;
using OPXF.Model;

foreach (var product in data.Data.Products)
{
    foreach (var (attrId, entry) in product.Attributes ?? [])
    {
        // Value shape depends on the model's localizable flag:
        //   localizable: false → string | double | bool | string[] | JsonElement
        //   localizable: true  → IReadOnlyDictionary<string, object> keyed by BCP 47 locale
        if (entry.Value is IReadOnlyDictionary<string, object> localeMap)
        {
            var enValue = localeMap["en-GB"];
        }
        else
        {
            var value = entry.Value;
        }
    }
}

Namespaces

Namespace Contents
OPXF OpxfSerializer — entry point for serialization
OPXF.Model OpxfModelFile, ModelDefinition, AttributeDefinition, AttributeType, ProductType, ObjectType, AssetType, CategoryType, Channel, AttributeGroup, SelectValue
OPXF.Data OpxfDataFile, DataPayload, Product, Variant, OpxfObject, Asset, AttributeMap, AttributeValueEntry, CategoryGroup, CategoryNode
OPXF.Validation OPXFValidator, ValidationResult, ValidationError

Conformance validation

OPXFValidator.Validate() enforces the cross-file rules from docs/conformance.md — constraints that JSON Schema alone cannot express. Each ValidationError carries:

  • RuleId — the conformance rule code, e.g. CONF-02
  • Message — human-readable description of the violation
  • Path — RFC 6901 JSON Pointer to the offending element, e.g. /data/products/0/productTypeId

OPXFValidator.ValidateModel() validates model internal integrity (CONF-31 through CONF-43) without a data file.

Validators collect all violations in a single pass — a payload returns all errors at once, not just the first.

Transfer mode

opxf.transferMode in the data file is advisory. When set to "incremental", referential existence rules (CONF-28, CONF-29, CONF-38) are relaxed — missing targets are the exporter's responsibility. When absent or unrecognised, "snapshot" semantics apply (strict enforcement).

Conformance rules implemented

Section 1 — Model/Data binding

Rule Description
CONF-01 opxf.modelId in the data file must equal model.id in the model file

Section 2 — Products

Rule Description
CONF-02 product.productTypeId must reference a defined product type
CONF-03 Every product.categories entry must reference a defined category node
CONF-04 Product attribute ids must be declared in productType.productAttributes
CONF-05 No two products may share the same id

Section 3 — Variants

Rule Description
CONF-06 Variant attribute ids must be declared in productType.variantAttributes; partial coverage allowed
CONF-07 No two variants within the same product may share the same id

Section 4 — Objects

Rule Description
CONF-09 objectTypeId must reference a defined object type
CONF-10 Object attribute ids must be declared in the resolved objectType.attributeDefinitions
CONF-11 No two objects within the same type group may share the same id

Section 5 — Assets

Rule Description
CONF-12 assetTypeId must reference a defined asset type
CONF-13 Asset attribute ids must be declared in the resolved assetType.attributeDefinitions
CONF-14 No two assets within the same type group may share the same id

Section 6 — Attribute value types

Rule Description
CONF-15 Attributes with localizable: true must have value as a locale-keyed object
CONF-16 Attributes with localizable: false must have value as a direct primitive
CONF-17 Every locale key in any locale-keyed object (attribute values and all labels) must be in model.locales
CONF-18 boolean values must be a JSON boolean — not the string "true"
CONF-19 number values must be a JSON number
CONF-20 text, textarea, and datetime values must be a string
CONF-21 text-list values must be an array of strings
CONF-22 select values must match a selectValue id; localizable select allows different ids per locale
CONF-23 select-list values must be an array of valid selectValue ids
CONF-24 object-link values must reference an existing object id in the correct type group
CONF-25 object-link-list values must be an array of existing object ids in the correct type group
CONF-26 asset-link values must reference an existing asset id in the correct type group
CONF-27 asset-link-list values must be an array of existing asset ids in the correct type group
CONF-28 product-link values must reference an existing product or variant id (snapshot mode only)
CONF-29 product-link-list values must be an array of existing product or variant ids (snapshot mode only)
CONF-30 json attributes accept any valid JSON value — no further enforcement

Section 7 — Categories

Rule Description
CONF-44 categoryTreeId values must be unique across all groups in data.categories
CONF-45 A category node with attribute keys must belong to a group that declares a categoryTypeId
CONF-46 Category node ids must be unique across the entire tree at all depths
CONF-47 Category node attribute ids must be declared in the resolved categoryType.attributeDefinitions
CONF-49 categoryTypeId on a category group must reference a defined categoryType
CONF-50 categoryType ids must be unique within model.categoryTypes

Section 8 — Model internal integrity

Rule Description
CONF-31 productType.productAttributes ids must exist in productAttributeDefinitions
CONF-32 productType.variantAttributes ids must exist in productAttributeDefinitions
CONF-33 Attribute definition ids within each objectType must be unique
CONF-34 Attribute definition ids within each assetType must be unique
CONF-35 selectValue ids within each attribute must be unique
CONF-36 attributeDefinition.objectTypeId must reference a defined objectType
CONF-37 attributeDefinition.assetTypeId must reference a defined assetType
CONF-39 channel.locales must be a subset of model.locales
CONF-40 model.defaultLocale must be present in model.locales
CONF-41 ids within each model-root array must be unique within that array
CONF-43 attributeDefinition.groupId must reference a defined attributeGroup in the correct scope

Section 9 — Entity id format

Rule Description
CONF-51 All ids must match ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ (also enforced by JSON Schema)

Section 10 — Cross-file references

Rule Description
CONF-38 channel.categoryTreeIds must reference trees present in data.categories (snapshot mode only)

Attribute types

The AttributeType class exposes string constants for all OPXF canonical types:

AttributeType.Text            // "text"
AttributeType.TextList        // "text-list"
AttributeType.Textarea        // "textarea"
AttributeType.Number          // "number"
AttributeType.Boolean         // "boolean"
AttributeType.Datetime        // "datetime"
AttributeType.Select          // "select"
AttributeType.SelectList      // "select-list"
AttributeType.AssetLink       // "asset-link"
AttributeType.AssetLinkList   // "asset-link-list"
AttributeType.ObjectLink      // "object-link"
AttributeType.ObjectLinkList  // "object-link-list"
AttributeType.ProductLink     // "product-link"
AttributeType.ProductLinkList // "product-link-list"
AttributeType.Json            // "json"
Repository Description
opxf/opxf-spec The OPXF specification — JSON schemas and conformance rules
opxf/opxf-dotnet-akeneo Akeneo → OPXF exporter built on this library
opxf/opxf-org Source for opxf.org

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0 92 6/23/2026
0.2.1 99 6/16/2026
0.2.0 98 6/12/2026
0.1.0 113 5/29/2026