user9148986
user9148986

Reputation:

Deserialize XML with multiple VARYING namespaces?

I'm trying to deserialize XML reports. This is the class that gets generated from the XML (class is fine). However, the namespaces do vary between SQL-server versions.

e.g. the report namespace which is

"http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition"

in the below example could also be

"http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition"

etc.

Also I'm presuming this namespace can vary

"http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"

How can I deserialize XML with varying namespace (without creating a separate class for every possible namespace) ?

This is my XML-class:

using System.Xml.Serialization;
using System.Collections.Generic;


namespace Xml2CSharp 
{
   [XmlRoot(ElementName = "DataSource",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class DataSource
   {
       [XmlElement(ElementName = "DataSourceReference",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string DataSourceReference { get; set; }

       [XmlElement(ElementName = "SecurityType",
           Namespace = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")]
       public string SecurityType { get; set; }

       [XmlElement(ElementName = "DataSourceID",
           Namespace = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")]
       public string DataSourceID { get; set; }

       [XmlAttribute(AttributeName = "Name")]
       public string Name { get; set; }
   }

   [XmlRoot(ElementName = "DataSources",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class DataSources
   {
       [XmlElement(ElementName = "DataSource",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public DataSource DataSource { get; set; }
   }

   [XmlRoot(ElementName = "QueryParameter",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class QueryParameter
   {
       [XmlElement(ElementName = "Value",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string Value { get; set; }

       [XmlAttribute(AttributeName = "Name")]
       public string Name { get; set; }
   }

   [XmlRoot(ElementName = "QueryParameters",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class QueryParameters
   {
       [XmlElement(ElementName = "QueryParameter",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public List<QueryParameter> QueryParameter { get; set; }
   }

   [XmlRoot(ElementName = "Query",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class Query
   {
       [XmlElement(ElementName = "DataSourceName",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string DataSourceName { get; set; }

       [XmlElement(ElementName = "QueryParameters",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public QueryParameters QueryParameters { get; set; }

       [XmlElement(ElementName = "CommandType",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string CommandType { get; set; }

       [XmlElement(ElementName = "CommandText",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string CommandText { get; set; }

       [XmlElement(ElementName = "Timeout",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string Timeout { get; set; }

       [XmlElement(ElementName = "UseGenericDesigner",
           Namespace = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")]
       public string UseGenericDesigner { get; set; }
   }

   [XmlRoot(ElementName = "Field",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class Field
   {
       [XmlElement(ElementName = "DataField",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string DataField { get; set; }

       [XmlElement(ElementName = "TypeName",
           Namespace = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")]
       public string TypeName { get; set; }

       [XmlAttribute(AttributeName = "Name")]
       public string Name { get; set; }
   }

   [XmlRoot(ElementName = "Fields",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class Fields
   {
       [XmlElement(ElementName = "Field",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public List<Field> Field { get; set; }
   }

   [XmlRoot(ElementName = "DataSet",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class DataSet
   {
       [XmlElement(ElementName = "Query",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public Query Query { get; set; }

       [XmlElement(ElementName = "Fields",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public Fields Fields { get; set; }

       [XmlAttribute(AttributeName = "Name")]
       public string Name { get; set; }
   }

   [XmlRoot(ElementName = "DataSets",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class DataSets
   {
       [XmlElement(ElementName = "DataSet",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public List<DataSet> DataSet { get; set; }
   }

   [XmlRoot(ElementName = "Values",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class Values
   {
       [XmlElement(ElementName = "Value",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string Value { get; set; }
   }

   [XmlRoot(ElementName = "DefaultValue",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class DefaultValue
   {
       [XmlElement(ElementName = "Values",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public Values Values { get; set; }

       [XmlElement(ElementName = "DataSetReference",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public DataSetReference DataSetReference { get; set; }
   }

   [XmlRoot(ElementName = "ReportParameter",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class ReportParameter
   {
       [XmlElement(ElementName = "DataType",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string DataType { get; set; }

       [XmlElement(ElementName = "DefaultValue",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public DefaultValue DefaultValue { get; set; }

       [XmlElement(ElementName = "Prompt",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string Prompt { get; set; }

       [XmlElement(ElementName = "Hidden",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string Hidden { get; set; }

       [XmlAttribute(AttributeName = "Name")]
       public string Name { get; set; }

       [XmlElement(ElementName = "ValidValues",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public ValidValues ValidValues { get; set; }
   }

   [XmlRoot(ElementName = "DataSetReference",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class DataSetReference
   {
       [XmlElement(ElementName = "DataSetName",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string DataSetName { get; set; }

       [XmlElement(ElementName = "ValueField",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string ValueField { get; set; }

       [XmlElement(ElementName = "LabelField",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string LabelField { get; set; }
   }

   [XmlRoot(ElementName = "ValidValues",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class ValidValues
   {
       [XmlElement(ElementName = "DataSetReference",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public DataSetReference DataSetReference { get; set; }
   }

   [XmlRoot(ElementName = "ReportParameters",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class ReportParameters
   {
       [XmlElement(ElementName = "ReportParameter",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public List<ReportParameter> ReportParameter { get; set; }
   }

   [XmlRoot(ElementName = "Report",
       Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
   public class Report
   {
       [XmlElement(ElementName = "AutoRefresh",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string AutoRefresh { get; set; }

       [XmlElement(ElementName = "DataSources",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public DataSources DataSources { get; set; }

       [XmlElement(ElementName = "DataSets",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public DataSets DataSets { get; set; }

       [XmlElement(ElementName = "ReportParameters",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public ReportParameters ReportParameters { get; set; }

       [XmlElement(ElementName = "Code",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string Code { get; set; }

       [XmlElement(ElementName = "Language",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string Language { get; set; }

       [XmlElement(ElementName = "ConsumeContainerWhitespace",
           Namespace = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition")]
       public string ConsumeContainerWhitespace { get; set; }

       [XmlElement(ElementName = "ReportUnitType",
           Namespace = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")]
       public string ReportUnitType { get; set; }

       [XmlElement(ElementName = "ReportID",
           Namespace = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")]
       public string ReportID { get; set; }

       [XmlAttribute(AttributeName = "xmlns")]
       public string Xmlns { get; set; }

       [XmlAttribute(AttributeName = "rd", Namespace = "http://www.w3.org/2000/xmlns/")]
       public string Rd { get; set; }
   }
}

Upvotes: 0

Views: 453

Answers (1)

Stefan Steiger
Stefan Steiger

Reputation: 82396

How about reading the namespace, then replacing it in text, and then deserialize from the replaced text ?
Since you have a report, the chances of the namespace-text appearing somewhere in content should be remote...

public RdlReader OpenXml(string xml)
{
    System.Xml.XmlDocument document = new System.Xml.XmlDocument();
    document.XmlResolver = null;
    document.PreserveWhitespace = true;
    document.LoadXml(xml);

    string default_namespace = Xml2CSharp.Report.DEFAULT_NAMESPACE;
    string designer_namespace = Xml2CSharp.Report.DESIGNER_NAMESPACE;

    if (document.DocumentElement.HasAttribute("xmlns"))
        default_namespace = document.DocumentElement.Attributes["xmlns"].Value;

    if (document.DocumentElement.HasAttribute("xmlns:rd"))
        designer_namespace = document.DocumentElement.Attributes["xmlns:rd"].Value;

    this.m_xml = xml
        .Replace(default_namespace, Xml2CSharp.Report.DEFAULT_NAMESPACE)
        .Replace(designer_namespace, Xml2CSharp.Report.DESIGNER_NAMESPACE);

    document = null;


    document = new System.Xml.XmlDocument();
    document.XmlResolver = null;
    document.PreserveWhitespace = true;
    document.LoadXml(this.m_xml);


    Xml2CSharp.Report rep = Tools.XML.Serialization.DeserializeXmlFromString<Xml2CSharp.Report>(this.m_xml);
    System.Console.WriteLine(rep);

    this.m_document = document;
    this.m_nsmgr = GetReportNamespaceManager(this.m_document);

    return this;
}

Like this:

[XmlRoot(ElementName = "Report",
    Namespace = Report.DEFAULT_NAMESPACE)]
public class Report
{
    public const string DEFAULT_NAMESPACE = "http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition";
    public const string DESIGNER_NAMESPACE = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner";
    [...]

Upvotes: 0

Related Questions