How to deserialize xml with xmlns? - c#

Ho do you deserialze xml with a xmlns? Below is the simplified xml containing the xmlns attribute and it fails to deserialize with the code below. The inner exception that I keep getting is:
{"<nzb xmlns='http://www.nzb.com'> was not expected."}
Code
TextReader tr = new StreamReader("nzb.xml");
XmlReaderSettings settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore };
XmlReader xmlReader = XmlReader.Create(tr, settings);
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "nzb";
xRoot.IsNullable = true;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Nzb), xRoot);
Nzb nzbFile = (Nzb)xmlSerializer.Deserialize(xmlReader);
xmlReader.Close();
Nzb Class
[XmlRoot("nzb", Namespace = "urn:http://www.nzb.com")]
public class Nzb
{
}
nzb.xml
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE nzb>
<nzb xmlns="http://www.nzb.com">
</nzb>

Your XML root attribute overrides are causing the problem in XmlSerialiser. This is already defined in the XmlRoot attribute of class Nzb. So the following will work:
XmlReader xmlReader = XmlReader.Create(tr, settings);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Nzb));
Nzb nzbFile = (Nzb)xmlSerializer.Deserialize(xmlReader);
xmlReader.Close();
However, you will need to change the Nzb XMLRoot attribute's namespace to:
[XmlRoot("nzb", Namespace = "http://www.nzb.com")]

Related

XmlWriter including namespace\schema for each tag

I need to create a file in XML using XmlWriter including for each tag the namespace\schema.
First I have a class produced by xsd schema file, I create the class with all objects and finally I serialize the class writing xml:
myclass root = new myclass();
root.val1 = "temp1";
root.val2 = "temp2";
[...]
using (XmlWriter writer = XmlWriter.Create(Path.Combine("myfile.xml"), s))
{
serializer.Serialize(writer, root);
the problem is that it creates the tags like that:
<Message>
<val1> temp1 </val1>
<val2> temp2 </val2>
<Message>
I want to write the tags as:
<temp:Message>
<temp:val1> temp1 </val1>
<temp:val2> temp2 </val2>
<temp:Message>
can I use some attribute in my class to add temp: starting tags?
I need also to add to my root tag some namespace:
<temp:Message
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="myxml.xsd"
xmlns:stf="urn:oecd:ties:stf:v4"
xmlns:mesage="urn:oecd:ties:cbc:v1"
xmlns:iso="urn:oecd:ties:isocbctypes:v1"
version="1.0">
so I need to add to root class:
1) xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2) xsi:schemaLocation="myxml.xsd"
3) xmlns:mesage="urn:oecd:ties:cbc:v1"
4) etc...
how can I do that?
you can attache temp by doing as below , attach namespace with you xml
var xsn = new XmlSerializerNamespaces();
xsn.Add("temp", "http://namespaceforxml");
XmlSerializer s = new XmlSerializer(typeof(Message));
Message msg = new Message();
// Writing a file requires a TextWriter.
TextWriter t = new StreamWriter(filename);
s.Serialize(t,msg,ns);
t.Close();
decorate calss as below
[XmlRoot(ElementName = "Message", Namespace = "//namespaceforxml")]
public class Message
{
[XmlElement(ElementName = "val1")]
public string val1{ get; set; }
}

XML serialize - remove first default tag [duplicate]

I've written some .net code to serialize an object using the XMLSerializer class.
public static string serialize(object o)
{
Type type = o.GetType();
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(type);
System.IO.StringWriter writer = new System.IO.StringWriter();
serializer.Serialize(writer, o);
return writer.ToString();
}
The output looks like this:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>a</string>
<string>b</string>
<string>c</string>
</ArrayOfString>
That's great, but what I would really like is to get just the root node without the XML doctype declaration at the beginning.
The reason I want to do this is because I would like to use the root element of the XML serialized object as part of another XML document.
XmlWriterSettings has a property to omit the XML declaration (OmitXmlDeclaration):
public static string Serialize(object obj)
{
var builder = new StringBuilder();
var xmlSerializer = new XmlSerializer(obj.GetType());
using (XmlWriter writer = XmlWriter.Create(builder,
new XmlWriterSettings() { OmitXmlDeclaration = true }))
{
xmlSerializer.Serialize(writer, obj);
}
return builder.ToString();
}

Generated CS class from xml schema

I did generate C# class form scham using xsd.exe (VS 2010 command prompt),
but when I serialize class to xml file, in the out file I don't have entry for schema.
Serialized xml:
<?xml version="1.0" encoding="utf-16"?>
<Dokumenty xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" idSystemuLokalnego="ASD" dataUtworzenia="0001-01-01T00:00:00">
<Wniosek>
<Beneficjent />
</Wniosek>
When I try to validate with schema using code:
//Serilalize xml to string
StringWriter sw = new StringWriter();
XmlTextWriter xw = new XmlTextWriter(sw);
x.Serialize(xw, doc);
String xml = sw.ToString();
StringReader sr = new StringReader(xml);
XmlTextReader xtr = new XmlTextReader(sr);
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add("", "schemas\\SimWniosekApl_v2.0.xsd");
settings.ValidationType = ValidationType.Schema;
//XmlReader reader = XmlReader.Create(xtr);
XmlDocument document = new XmlDocument();
document.Load(xtr);
ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationHandler);
// the following call to Validate succeeds.
document.Validate(eventHandler);
It fails with exception:
Additional information: The XmlSchemaSet on the document is either null or has no schemas in it. Provide schema information before calling Validate.
What do I do wrong?
you need to apply the XmlReaderSettings when you create the reader.
That code does nothing with the settings. The reader has been created already, before the settings are created. The code simply creates settings and then forgets them.
StringReader sr = new StringReader(xml);
//XmlTextReader xtr = new XmlTextReader(sr);
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add("", "schemas\\SimWniosekApl_v2.0.xsd");
settings.ValidationType = ValidationType.Schema;
XmlReader reader = XmlReader.Create(xtr,settings);
XmlDocument document = new XmlDocument();
document.Load(reader);
ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationHandler);
document.Validate(eventHandler);
There is a full example here:
http://msdn.microsoft.com/en-us/library/ms162371.aspx

Convert an in memory schema-free XmlDocument into a schema-aware (xsd-backed) XmlDocument

I'm trying to write this method:
XmlDocument AddSchemaToRootNode(XmlDocument xmlDocument, string schema)
{
}
The input document comes from a expensive-to-change application (written in .Net 2.0). The output is consumed by an XSD-aware XmlSerializer.
I have unit tests that show that I need the xmlns="http://wibble/wobble/wubble" qualifier on the root element in order for the XmlSerializer to work. The untyped-XmlReader doesn't care. How do I get the xmlns qualifier written in?
You need to inject your namespace using XmlAttributeOverrides. This collection is passed into the XmlSerializer constructor.
To override the root element:
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
var rootNode = new XmlRootAttribute()
{
ElementName = "MyRootNodeName",
Namespace = "http://wibble/wobble/wubble"
};
var newAttribute = new XmlAttributes();
newAttribute.XmlRoot = rootNode;
overrides.Add(typeof(MyType), newAttribute);
To call the serilaizer:
XmlSerializer serializer = new XmlSerializer(typeof(MyType), overrides);
You can also override any other node in the XML using XmlAttributeOverrides. XmlAttributeOverrides is your friend!
Hope this helps.

How to deserialize an Xml Fragment using the XML Reader

I am trying to deserialize a Xml Fragment. I am nearly there but it throws an error where by it does not expect the first element. An example of the XML in the stream is as follows:
<Project xmlns="http://schemas.datacontract.org/2004/07/Swissmod.Service.Model" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ClientID>1</ClientID>
<Created>2009-03-16T20:34:57.022167+00:00</Created>
<ID>22</ID>
<LastModified>2009-03-11T20:34:57.022167+00:00</LastModified>
<ProjectDescription>Description here</ProjectDescription>
<ProjectTitle>Poject title</ProjectTitle>
<UserID>5</UserID>
<Version>1234567</Version>
</Project>
I am using the following code to deserialize:
XmlSerializer serializer = new XmlSerializer(typeof(Project));
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationFlags = XmlSchemaValidationFlags.None;
settings.ValidationType = ValidationType.None;
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IgnoreProcessingInstructions = true;
settings.NameTable = new NameTable();
settings.NameTable.Add("http://schemas.datacontract.org/2004/07/Swissmod.Service.Model");
XmlReader reader = XmlReader.Create(wresp.GetResponseStream(),settings);
Project p = (Project)serializer.Deserialize(reader);
But the above throws the following error:
There is an error in XML document (1, 2).
"<Project xmlns='http://schemas.datacontract.org/2004/07/Swissmod.Service.Model'> was not expected."
Anyone have any ideas how I can read an XML Fragment using a XML Reader?
In your Project class definition, have you tried specifying a namespace in an XmlRoot attribute?

Categories

Resources