Skip to content

Commit

Permalink
Fixed issue with XML namespace schema while decode an XML nodeset (#1385
Browse files Browse the repository at this point in the history
)

- added protected property XmlNamespace to BaseComplexType class
- use XmlNamespace instead of TypeId.NamespaceUri for PushNamespace of
  encoder/decoder
- adapt Encode/Decode method in OptionalFieldsCompexType and
  UnionComplexType class

Change was needed if Xml schema in Xml nodeset differ from the custom OPC UA namespace. 
Only effects XML encoding and decoding from values of customized structured datatypes.

Example:

The OPC UA Namespace of the nodeset is http://MyTestOfExtensions but the xml namespace for the xml schema is http://MyTestOfExtensions/Types.xsd
These 2 namespaces are not forced to be equal, therefor the XmlDecoder need to Push the XmlNamespace for the schema to the Reader stack. Otherwise the ExtensionObject Body will not be read.

```XML
<?xml version="1.0" encoding="utf-8"?>
<UANodeSet LastModified="2021-04-08T11:57:22.286Z" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd" xmlns:si="http://www.siemens.com/OPCUA/2017/SimaticNodeSetExtensions" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <NamespaceUris>
        <Uri>http://MyTestOfExtensions</Uri>
    </NamespaceUris>
    <Models>
        <Model ModelUri="http://MyTestOfExtensions" PublicationDate="2020-07-20T00:00:00Z" Version="1.00">
            <RequiredModel ModelUri="http://opcfoundation.org/UA/" PublicationDate="2020-07-15T00:00:00Z" Version="1.04.7"/>
        </Model>
    </Models>
    <Aliases>
        <Alias Alias="Boolean">i=1</Alias>
        <Alias Alias="DateTime">i=13</Alias>
        <Alias Alias="String">i=12</Alias>
        <Alias Alias="NodeId">i=17</Alias>
        <Alias Alias="QualifiedName">i=20</Alias>
        <Alias Alias="HasComponent">i=47</Alias>
        <Alias Alias="HasProperty">i=46</Alias>
        <Alias Alias="Organizes">i=35</Alias>
        <Alias Alias="HasSubtype">i=45</Alias>
        <Alias Alias="HasTypeDefinition">i=40</Alias>
        <Alias Alias="HasModellingRule">i=37</Alias>
        <Alias Alias="HasEncoding">i=38</Alias>
    </Aliases>
    <Extensions>
        <Extension>
            <si:Generator Product="SiOME" Edition="Standard" Version="2.2.3-beta24"/>
        </Extension>
        <Extension>
            <si:GeneratorExtension Hash="cee97a4b7b32c169214c2bbc22b555d2"/>
        </Extension>
    </Extensions>
    <UAObject SymbolicName="http___MyTestOfExtensions" NodeId="ns=1;i=5000" BrowseName="1:http://MyTestOfExtensions" ParentNodeId="i=11715">
        <DisplayName>http://MyTestOfExtensions</DisplayName>
        <References>
            <Reference ReferenceType="HasComponent" IsForward="false">i=11715</Reference>
            <Reference ReferenceType="HasTypeDefinition">i=11616</Reference>
        </References>
    </UAObject>
    <UAVariable DataType="String" NodeId="ns=1;i=6002" BrowseName="NamespaceUri" ParentNodeId="ns=1;i=5000">
        <DisplayName>NamespaceUri</DisplayName>
        <References>
            <Reference ReferenceType="HasProperty" IsForward="false">ns=1;i=5000</Reference>
            <Reference ReferenceType="HasTypeDefinition">i=68</Reference>
        </References>
        <Value>
            <uax:String>http://MyTestOfExtensions</uax:String>
        </Value>
    </UAVariable>
    <UADataType NodeId="ns=1;i=3000" BrowseName="1:MyStructureType">
        <DisplayName>MyStructureType</DisplayName>
        <References>
            <Reference ReferenceType="HasSubtype" IsForward="false">i=22</Reference>
            <Reference ReferenceType="HasEncoding">ns=1;i=5001</Reference>
            <Reference ReferenceType="HasEncoding">ns=1;i=5002</Reference>
        </References>
        <Definition Name="1:MyStructureType">
            <Field DataType="i=17" Name="NodeId"/>
            <Field DataType="i=20" Name="QualifiedName"/>
        </Definition>
    </UADataType>
    <UAObject SymbolicName="DefaultBinary" NodeId="ns=1;i=5001" BrowseName="Default Binary">
        <DisplayName>Default Binary</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">i=76</Reference>
        </References>
    </UAObject>
    <UAObject SymbolicName="DefaultXML" NodeId="ns=1;i=5002" BrowseName="Default XML">
        <DisplayName>Default XML</DisplayName>
        <References>
            <Reference ReferenceType="HasTypeDefinition">i=76</Reference>
        </References>
    </UAObject>
    <UAVariable DataType="ns=1;i=3000" NodeId="ns=1;i=6021" BrowseName="1:StructureTest" ParentNodeId="i=2253" UserAccessLevel="3" AccessLevel="3">
        <DisplayName>StructureTest</DisplayName>
        <References>
            <Reference ReferenceType="Organizes" IsForward="false">i=2253</Reference>
            <Reference ReferenceType="HasTypeDefinition">i=63</Reference>
        </References>
        <Value>
            <uax:ExtensionObject>
                <uax:TypeId>
                    <uax:Identifier>ns=1;i=5002</uax:Identifier>
                </uax:TypeId>
                <uax:Body>
                    <MyStructureType xmlns="http://MyTestOfExtensions/Types.xsd">
                        <NodeId>
                            <uax:Identifier>ns=1;i=42</uax:Identifier>
                        </NodeId>
                        <QualifiedName>
                            <uax:NamespaceIndex>1</uax:NamespaceIndex>
                            <uax:Name>zweiundvierzig</uax:Name>
                        </QualifiedName>
                    </MyStructureType>
                </uax:Body>
            </uax:ExtensionObject>
        </Value>
    </UAVariable>
</UANodeSet>
```
  • Loading branch information
SBaeumler committed Apr 30, 2021
1 parent aba60b9 commit ea1e2b3
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
30 changes: 27 additions & 3 deletions Libraries/Opc.Ua.Client.ComplexTypes/Types/BaseComplexType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ public new virtual object MemberwiseClone()
/// <summary cref="IEncodeable.Encode(IEncoder)" />
public virtual void Encode(IEncoder encoder)
{
encoder.PushNamespace(TypeId.NamespaceUri);

encoder.PushNamespace(XmlNamespace);
foreach (var property in GetPropertyEnumerator())
{
EncodeProperty(encoder, property.PropertyInfo, property.ValueRank);
Expand All @@ -138,7 +138,7 @@ public virtual void Encode(IEncoder encoder)
/// <summary cref="IEncodeable.Decode(IDecoder)" />
public virtual void Decode(IDecoder decoder)
{
decoder.PushNamespace(TypeId.NamespaceUri);
decoder.PushNamespace(XmlNamespace);

foreach (var property in GetPropertyEnumerator())
{
Expand Down Expand Up @@ -270,6 +270,7 @@ public virtual IEnumerable<ComplexTypePropertyAttribute> GetPropertyEnumerator()
#endregion IComplexTypeProperties

#region Private Members

/// <summary>
/// Formatting helper.
/// </summary>
Expand Down Expand Up @@ -937,6 +938,27 @@ protected virtual void InitializePropertyAttributes()
}
#endregion Private Members


#region Protected Properties

/// <summary>
/// Provide XmlNamespace based on systemType
/// </summary>
protected string XmlNamespace
{
get
{
if (m_xmlName == null)
{
m_xmlName = EncodeableFactory.GetXmlName(GetType());
}

return m_xmlName != null ? m_xmlName.Namespace : string.Empty;
}
}

#endregion

#region Protected Fields
/// <summary>
/// The list of properties of this complex type.
Expand All @@ -951,6 +973,8 @@ protected virtual void InitializePropertyAttributes()
#region Private Fields
private ServiceMessageContext m_context;
private StructureBaseDataType m_structureBaseType;
private XmlQualifiedName m_xmlName;
#endregion Private Fields

}
}//namespace
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public override object MemberwiseClone()
/// <summary cref="IEncodeable.Encode(IEncoder)" />
public override void Encode(IEncoder encoder)
{
encoder.PushNamespace(TypeId.NamespaceUri);
encoder.PushNamespace(XmlNamespace);

if (encoder.UseReversibleEncoding)
{
Expand All @@ -109,7 +109,7 @@ public override void Encode(IEncoder encoder)
/// <summary cref="IEncodeable.Decode(IDecoder)" />
public override void Decode(IDecoder decoder)
{
decoder.PushNamespace(TypeId.NamespaceUri);
decoder.PushNamespace(XmlNamespace);

m_encodingMask = decoder.ReadUInt32("EncodingMask");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public override object MemberwiseClone()
/// <summary cref="IEncodeable.Encode(IEncoder)" />
public override void Encode(IEncoder encoder)
{
encoder.PushNamespace(TypeId.NamespaceUri);
encoder.PushNamespace(XmlNamespace);

string fieldName = null;
if (encoder.UseReversibleEncoding)
Expand Down Expand Up @@ -122,7 +122,7 @@ public override void Encode(IEncoder encoder)
/// <summary cref="IEncodeable.Decode(IDecoder)" />
public override void Decode(IDecoder decoder)
{
decoder.PushNamespace(TypeId.NamespaceUri);
decoder.PushNamespace(XmlNamespace);

m_switchField = decoder.ReadUInt32("SwitchField");

Expand Down

0 comments on commit ea1e2b3

Please sign in to comment.