Skip to content

Commit 201cc6f

Browse files
committed
Merge PR TrakHound#223 feat/configuration-vendor-extensions into integration/up-to-pr-223
2 parents 9f4a179 + c0b72bf commit 201cc6f

13 files changed

Lines changed: 2016 additions & 2 deletions

File tree

build/MTConnect.NET-SysML-Import/CSharp/TemplateRenderer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ public static void Render(MTConnectModel mtconnectModel, string outputPath)
176176

177177
case "Devices.Component": ((ClassModel)template).IsPartial = true; break;
178178
case "Devices.Composition": ((ClassModel)template).IsPartial = true; break;
179+
case "Devices.Configurations.Configuration": ((ClassModel)template).IsPartial = true; break;
179180
case "Devices.DataItem": ((ClassModel)template).IsPartial = true; break;
180181
case "Devices.AbstractDataItemRelationship": ((ClassModel)template).IsPartial = true; break;
181182
case "Devices.References.Reference": ((ClassModel)template).IsPartial = true; break;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) 2026 TrakHound Inc., All Rights Reserved.
2+
// TrakHound Inc. licenses this file to you under the MIT license.
3+
4+
using System.Collections.Generic;
5+
using System.Xml.Linq;
6+
7+
namespace MTConnect.Devices.Configurations
8+
{
9+
/// <summary>
10+
/// Hand-authored partial extension of the generated <see cref="Configuration"/>
11+
/// concrete class that carries the vendor-extension collection declared on
12+
/// <see cref="IConfiguration.VendorExtensions"/>. See the interface's remarks
13+
/// for the MTConnect v2.7 XSD citation that underpins the semantics.
14+
/// </summary>
15+
public partial class Configuration
16+
{
17+
/// <inheritdoc cref="IConfiguration.VendorExtensions"/>
18+
public IEnumerable<XElement> VendorExtensions { get; set; }
19+
}
20+
}

libraries/MTConnect.NET-Common/Devices/Configurations/Configuration.g.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace MTConnect.Devices.Configurations
88
/// <summary>
99
/// Technical information about an entity describing its physical layout, functional characteristics, and relationships with other entities.
1010
/// </summary>
11-
public class Configuration : IConfiguration
11+
public partial class Configuration : IConfiguration
1212
{
1313
/// <summary>
1414
/// The description of this type as defined by the MTConnect Standard.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) 2026 TrakHound Inc., All Rights Reserved.
2+
// TrakHound Inc. licenses this file to you under the MIT license.
3+
4+
using System.Collections.Generic;
5+
using System.Xml.Linq;
6+
7+
namespace MTConnect.Devices.Configurations
8+
{
9+
/// <summary>
10+
/// Hand-authored partial extension of the generated <see cref="IConfiguration"/>
11+
/// contract that adds the vendor-extension surface. The MTConnect Standard
12+
/// itself defines vendor extension of a component's Configuration through the
13+
/// XSD substitution group <c>AbstractConfiguration</c> — see
14+
/// <c>MTConnectDevices_2.7.xsd</c> where <c>ComponentConfigurationType</c>
15+
/// declares <c>&lt;xs:element ref="AbstractConfiguration" minOccurs="0"
16+
/// maxOccurs="unbounded"/&gt;</c>, and every standard child (SensorConfiguration,
17+
/// Specifications, Relationships, CoordinateSystems, Motion, SolidModel,
18+
/// ImageFiles, PowerSources) is declared with
19+
/// <c>substitutionGroup='AbstractConfiguration'</c>. A vendor publishes their
20+
/// own XSD declaring a vendor-namespaced element that likewise substitutes for
21+
/// <c>AbstractConfiguration</c>, and the operator supplies fully-formed
22+
/// instances of that element through this collection.
23+
/// </summary>
24+
public partial interface IConfiguration
25+
{
26+
/// <summary>
27+
/// Vendor-extension elements carried inside the component's
28+
/// <c>&lt;Configuration&gt;</c>. Each entry MUST be a fully-formed,
29+
/// vendor-namespaced XML element that a vendor XSD declares as a
30+
/// substitution of the standard <c>AbstractConfiguration</c> abstract
31+
/// element (see class-level remarks for the MTConnect XSD citation).
32+
/// The MTConnect.NET XML formatter writes each element verbatim inside
33+
/// the <c>&lt;Configuration&gt;</c> sequence, alongside any standard
34+
/// children present on this instance; the deserialiser captures any
35+
/// child element it does not recognise as a standard configuration
36+
/// child and adds it here. Strict XSD validation of the emitted
37+
/// document is the caller's responsibility and requires the vendor XSD
38+
/// to be loaded alongside the MTConnect schemas.
39+
/// </summary>
40+
IEnumerable<XElement> VendorExtensions { get; }
41+
}
42+
}

libraries/MTConnect.NET-Common/Devices/Configurations/IConfiguration.g.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace MTConnect.Devices.Configurations
66
/// <summary>
77
/// Technical information about an entity describing its physical layout, functional characteristics, and relationships with other entities.
88
/// </summary>
9-
public interface IConfiguration
9+
public partial interface IConfiguration
1010
{
1111
/// <summary>
1212
/// Reference system that associates a unique set of n parameters with each point in an n-dimensional space. ISO 10303-218:2004

libraries/MTConnect.NET-XML/Devices/XmlConfiguration.cs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
using MTConnect.Devices.Configurations;
55
using System.Collections.Generic;
6+
using System.Linq;
67
using System.Xml;
8+
using System.Xml.Linq;
79
using System.Xml.Serialization;
810

911
namespace MTConnect.Devices.Xml
@@ -15,6 +17,18 @@ namespace MTConnect.Devices.Xml
1517
/// and converts to and from the strongly-typed <see cref="Configuration"/>
1618
/// model.
1719
/// </summary>
20+
/// <remarks>
21+
/// Any child element that is neither a standard configuration child nor a
22+
/// namespaced vendor extension declared on this surrogate is captured
23+
/// into <see cref="VendorExtensions"/> as a raw <see cref="XmlElement"/>
24+
/// via <see cref="XmlAnyElementAttribute"/>, then projected onto
25+
/// <see cref="IConfiguration.VendorExtensions"/> as an
26+
/// <see cref="XElement"/>. This mirrors the MTConnect XSD's
27+
/// <c>ComponentConfigurationType</c> which permits any element that
28+
/// substitutes for the abstract <c>AbstractConfiguration</c> element —
29+
/// i.e. any element a vendor XSD has declared with
30+
/// <c>substitutionGroup='AbstractConfiguration'</c>.
31+
/// </remarks>
1832
[XmlRoot("Configuration")]
1933
public class XmlConfiguration
2034
{
@@ -61,6 +75,16 @@ public class XmlConfiguration
6175
[XmlArrayItem("ProcessSpecification", typeof(XmlProcessSpecification))]
6276
public List<XmlAbstractSpecification> Specifications { get; set; }
6377

78+
/// <summary>
79+
/// Vendor-extension child elements captured verbatim from the
80+
/// <c>&lt;Configuration&gt;</c> element by <see cref="XmlAnyElementAttribute"/>
81+
/// — every child not bound to a strongly-typed slot above lands here.
82+
/// See <see cref="IConfiguration.VendorExtensions"/> for the standard
83+
/// citation.
84+
/// </summary>
85+
[XmlAnyElement]
86+
public XmlElement[] VendorExtensions { get; set; }
87+
6488

6589
/// <summary>
6690
/// Converts this surrogate into the strongly-typed
@@ -122,6 +146,27 @@ public IConfiguration ToConfiguration()
122146
configuration.Specifications = specifications;
123147
}
124148

149+
// Vendor Extensions — every unrecognised child element captured by
150+
// [XmlAnyElement] projects to an XElement on the model. Elements are
151+
// preserved verbatim so downstream consumers see the exact
152+
// vendor-namespaced XML the operator authored.
153+
if (VendorExtensions != null && VendorExtensions.Length > 0)
154+
{
155+
var extensions = new List<XElement>(VendorExtensions.Length);
156+
foreach (var element in VendorExtensions)
157+
{
158+
if (element != null)
159+
{
160+
extensions.Add(XElement.Parse(element.OuterXml, LoadOptions.PreserveWhitespace));
161+
}
162+
}
163+
164+
if (extensions.Count > 0)
165+
{
166+
configuration.VendorExtensions = extensions;
167+
}
168+
}
169+
125170
return configuration;
126171
}
127172

@@ -196,6 +241,20 @@ public static void WriteXml(XmlWriter writer, IConfiguration configuration, bool
196241
writer.WriteEndElement();
197242
}
198243

244+
// Write Vendor Extensions — each XElement is a fully-formed,
245+
// vendor-namespaced element that a vendor XSD declares as a
246+
// substitution of the standard AbstractConfiguration abstract
247+
// element. Serialise verbatim via WriteRaw so namespace
248+
// declarations and mixed content are preserved as authored.
249+
if (configuration.VendorExtensions != null)
250+
{
251+
foreach (var extension in configuration.VendorExtensions)
252+
{
253+
if (extension == null) continue;
254+
writer.WriteRaw(extension.ToString(SaveOptions.DisableFormatting));
255+
}
256+
}
257+
199258
writer.WriteEndElement();
200259
}
201260
}

0 commit comments

Comments
 (0)