David,
Now I am with you ... and tha bad news is that the XmlSerializer is not
really intended to do what you're trying to do. From an XML perspective,
you're trying to deserialize two entirely different XML formats. While the
two formats share the same element names, their QNames (name+namespace) are
different. An XmlSerializer is really only good at processing one format.
You may be able to work around this with two serializer instances. One that
you instantiate with
XmlSerializer ser1 = new XmlSerializer( typeof( TransferManifest ) );
and another one that you instantiate with XmlOverrideAttributes supplied to
the constructor:
<notTested>
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes atts = new XmlAttributes();
// override the XmlType and XmlRoot attributes
atts.XmlType = new XmlTypeAttribute();
atts.XmlRoot = new XmlRootAttribute();
overrides.Add( typeof( TransferManifest ), atts );
XmlSerializer ser2 = new XmlSerializer( typeof( TransferManifest ),
overrides );
</notTested>
then you read the first element of your XML document with an XmlTextReader
to determine if any namespaces are declared.
TransferManifest tm = null;
XmlTextReader reader = new XmlTextReader( new StringReader( xml ) );
if( reader.Read() )
{
if( reader.NamespaceURI = "" )
{
reader.Close();
tm = ser2.Deserialize( new StringReader( xml ) );
}
else
{
reader.Close();
tm = ser1.Deserialize( new StringReader( xml ) );
}
}
Let me know if this works ...
--
Christoph Schittko [MVP, XmlInsider]
Software Architect, .NET Mentor
"David B. Bitton" <da***@codenoevil.com> wrote in message
news:el**************@tk2msftngp13.phx.gbl...
Chris,
I am well aware of _why_ the exception occurs. Now I need a way to
work around it. How can I provide a "hint" to the XmlSerializer that if the
root node has either an empty xmlns, or none at all, that the root node
namespace _should_ be something, and it's OK if the node is missing the declaration.
--
--
David B. Bitton
da***@codenoevil.com
www.codenoevil.com
Code Made Fresh DailyT
"Christoph Schittko [MVP]" <ch********************@austin.rr.com> wrote in
message news:%2****************@tk2msftngp13.phx.gbl... David,
The code you posted works fine for me with this code:
TransferManifest mfst = new TransferManifest();
string xml = TransferManifest.WriteXml( mfst );
mfst = TransferManifest.ReadXml( xml );
but I removed the three array type properties
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("file list")]
public FileList[] FileLists;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("fold erlist")]
public FolderList[] FolderLists;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("uplo adinfo")]
public UploadInfo[] UploadInfos;
because I didn't have the class definitions.
The root element
<transfermanifest>
you posted would not deserialize because it's missing the XML namespace that you declared with the XmlRoot and XmlType attributes. The root element
needs a namespace declaration like this:
<transfermanifest xmlns=http://codenoevil.com/TransferManifest.xsd>
which your code produces.
You could either post more code, or follow the instructions at [0] on
how to debug deserialization.
--
HTH
Christoph Schittko [MVP]
Software Architect, .NET Mentor
"David B. Bitton" <da***@codenoevil.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl... Chris,
Look inline below:
--
--
David B. Bitton
da***@codenoevil.com
www.codenoevil.com
Code Made Fresh DailyT
"Christoph Schittko [MVP]" <ch********************@austin.rr.com>
wrote in message news:eN*************@TK2MSFTNGP12.phx.gbl...
> David,
>
> Can you post:
>
> * The serialization class
[System.Xml.Serialization.XmlTypeAttribute(Namespac e=TransferManifest.DEFAUL T_NAMESPACE)]
[System.Xml.Serialization.XmlRootAttribute(Namespac e=TransferManifest.DEFAUL
T_NAMESPACE, IsNullable=false, ElementName="transfermanifest")]
public class TransferManifest {
public const string DEFAULT_NAMESPACE =
"http://codenoevil.com/TransferManifest.xsd";
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("file list")]
public FileList[] FileLists;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("fold erlist")]
public FolderList[] FolderLists;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("uplo adinfo")]
public UploadInfo[] UploadInfos;
#region XML (de)serialization code
public static TransferManifest ReadXml(string xml)
{
XmlSerializer xmlSerializer =
new XmlSerializer(typeof(TransferManifest));
xmlSerializer.UnknownNode+= new
XmlNodeEventHandler(XmlSerializer_UnknownNode);
xmlSerializer.UnknownAttribute+= new
XmlAttributeEventHandler(XmlSerializer_UnknownAttr ibute);
try
{
TransferManifest transferManifest =
(TransferManifest)xmlSerializer.Deserialize(
new StringReader(xml)
);
return transferManifest;
}
catch(Exception ex)
{
throw new ApplicationException("TransferManifest failed to deserialize: " + ex.Message, ex);
}
}
public static string WriteXml(TransferManifest transferManifest)
{
XmlSerializer xmlSerializer =
new XmlSerializer(typeof(TransferManifest), DEFAULT_NAMESPACE);
StringWriter stringWriter = new StringWriter();
xmlSerializer.Serialize(stringWriter, transferManifest);
return stringWriter.ToString();
}
private static void XmlSerializer_UnknownNode
(object sender, XmlNodeEventArgs e)
{
Debug.WriteLine("Unknown Node:" + e.Name + "\t" + e.Text);
}
private static void XmlSerializer_UnknownAttribute
(object sender, XmlAttributeEventArgs e)
{
System.Xml.XmlAttribute attr = e.Attr;
Debug.WriteLine("Unknown attribute " +
attr.Name + "='" + attr.Value + "'");
}
#endregion
}
> * the tag of the root element, including all namespace definitions
<transfermanifest>
> * the line of code where you instantiate the XmlSerializer
Look inside the WriteXml() method above.
>
> --
> Christoph Schittko [MVP]
> Software Architect, .NET Mentor
>
> "David B. Bitton" <da***@codenoevil.com> wrote in message
> news:%2****************@tk2msftngp13.phx.gbl...
> > I am having a problem deserializing XML when the root node is
missing a > > namespace declaration. My Type has an XmlTypeAttribute with a
namespace > > defined. If I attempt to deserialize the XML, I get the dreaded
> >
> > <elementname xmlns=''> was not expected
> >
> > exception. If I comment out the XmlTypeAttribute, it works just
fine. > Just
> > so you know, when I instantiate an instance of an XmlSerializer, I
pass a
> > default namespace to the ctor. Unfortunately that doesn't seem to
work. > >
> > So, how can I get the XmlSerializer to accept XML that is missing
> namespace
> > declarations?
> >
> > --
> > --
> >
> > David B. Bitton
> > da***@codenoevil.com
> > www.codenoevil.com
> >
> > Code Made Fresh DailyT
> >
> >
>
>