0

I have been trying to deserialize an XML file and pull out some data from StructuredText element of the XML. So far, namespace have been causing issues.

I generated the classes with xsd from a schema but the classes have no namespace specified. I need to be able to use different namespaces so having them vary would be nice.

I tried defining the namespace in the root attribute but like that the deserialization only returns null. If I do not specify one I get an error from the deserializer on the StructuredText element.

    private StructuredText_T DeserializeStructuredText(string filePath) {
        StructuredText_T structuredText;

        XmlSerializer serializer = new XmlSerializer(typeof(TIAOpennessAppSclXsd.StructuredText_T),
        new XmlRootAttribute("StructuredText")
        {
            Namespace = "http://www.siemens.com/automation/Openness/SW/NetworkSource/StructuredText/v4",
            IsNullable = false
        });

        XmlReaderSettings settings = new XmlReaderSettings
        {
            CheckCharacters = false // Ignore invalid characters
        };

        using (XmlReader reader = XmlReader.Create(filePath, settings))
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element && reader.Name == "StructuredText")
                {
                    Console.WriteLine($"Deserialize {reader.NodeType} named {reader.Name}");
                    structuredText = (StructuredText_T)serializer.Deserialize(reader);
                    return (structuredText);
                }
            }

        return null;
    }

The deserialization only works if I change the XSD generated classes and specify the namespace inside the RootAttribute there like so:

[System.Xml.Serialization.XmlRootAttribute("StructuredText", Namespace="http://www.siemens.com/automation/Openness/SW/NetworkSource/StructuredText/v4", IsNullable=false)]

But this is something I want to avoid. First because there is a lot of classes and second because I need flexibility.

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute("StructuredText", Namespace="", IsNullable=false)]
public partial class StructuredText_T {
    private object[] itemsField;
    private int uIdField;
    private bool uIdFieldSpecified;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Access", typeof(Access_T))]
    [System.Xml.Serialization.XmlElementAttribute("Blank", typeof(Blank_T))]
    [System.Xml.Serialization.XmlElementAttribute("Comment", typeof(Comment_T))]
    [System.Xml.Serialization.XmlElementAttribute("LineComment", typeof(LineComment_T))]
    [System.Xml.Serialization.XmlElementAttribute("NewLine", typeof(NewLine_T))]
    [System.Xml.Serialization.XmlElementAttribute("Parameter", typeof(Parameter_T))]
    [System.Xml.Serialization.XmlElementAttribute("Text", typeof(Text_T))]
    [System.Xml.Serialization.XmlElementAttribute("Token", typeof(Token_T))]
    public object[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public int UId {
        get {
            return this.uIdField;
        }
        set {
            this.uIdField = value;
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool UIdSpecified {
        get {
            return this.uIdFieldSpecified;
        }
        set {
            this.uIdFieldSpecified = value;
        }
    }
}

What am I missing?

3
  • You need to URL of the namespace in the c# class definitions. Not just in the Root. The XmlElementAttribute has a Namespace string as an optional parameter. I would solve on issue at a time. Find where properties are missing and then add a Namespace String to the attribute of the property. Private properties are ignored in serialization so you may need to remove the private type from the variables. Commented Mar 23 at 11:47
  • @jdweng In that case what I was trying to do is not possible if I understand you correctly. That is to go around without changing XSD generated classes. Commented Mar 23 at 12:50
  • 1
    I missed the fact that your c# classes were generated from the schema. Probably it is not possible. Some industry standard schemas have user configurable elements and the configurable elements may have errors. So in your case the schema may be bad. Also your schema may be missing an "include" where some of the schema definitions comes from another schema. I've seen too many cases where people who generate XML never do a schema check on the XML files before distributing. Then users are left to find the errors. Commented Mar 23 at 20:59

1 Answer 1

0

In the end I just decided to go with the easiest and for me most flexible option by just ignoring the namespaces in the XML.

public class IgnoreNamespaceXmlTextReader : XmlTextReader
{
    public IgnoreNamespaceXmlTextReader(TextReader reader) : base(reader) { }

    public override string NamespaceURI => string.Empty; // Ignores all namespaces
}

Not saying its the best solution, but for my use I think I can afford to do this.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.