admin管理员组

文章数量:1401771

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 = ";,
            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=";, 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?

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/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/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?

Share Improve this question edited Mar 23 at 11:45 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 23 at 10:40 JohnnyHavlisJohnnyHavlis 133 bronze badges 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. – jdweng 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. – JohnnyHavlis 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. – jdweng Commented Mar 23 at 20:59
Add a comment  | 

1 Answer 1

Reset to default 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.

本文标签: cUnable to deserialize XML element with namespacesStack Overflow